完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
功能分析 本次省赛用到的模块不是很多,不过都是属于经典要考的内容。LED灯点亮,KEY按键控制,定时器双通道输出PWM,ADC模拟电压。以及界面显示等。总体来说初始化函数不难写。 源码分析 声明:为比赛上交文件方便原因,我把初始化程序和功能函数全写在Main.c里,就为了最后不会漏交文件,但这不是一个好习惯,在平时做项目时候建议大家文件模块化,条理更加清晰。 变量定义 #include "stm32f10x.h" #include "lcd.h" #include "stdio.h" #define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) #define KEY2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) #define KEY3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) #define KEY4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2) u32 TimingDelay = 0; //****定时器变量******// u16 TIM3_CH1_Fre; u16 TIM3_CH1_Duty; u8 TIM3_CH1_Flag=0; u16 TIM3_CH2_Fre; u16 TIM3_CH2_Duty; u8 TIM3_CH2_Flag=0; //*******************// void Delay_Ms(u32 nTime); void LED_Init(void); void KEY_Init(void); void ADC1_Init(void); void PWM3_OUT(u16 Frequency1,u8 Duty1,u16 Frequency2,u8 Duty2); void KEY_Read(void); float ADC_Read(void); u8 zhankong1=10;//占空比10 u8 zhankong2=10;//占空比10 u8 biankong1=10; u8 biankong2=10; u8 Set_Flag=0;//界面跳转标志 u8 Control_Flag;//模式跳转标志 //******中断标志变量*********// u8 KEY_Flag=0; u8 ADC_Flag=0; u8 Display_Flag; u8 LED_Flag=0; u8 Time_Flag=0; //**************************// int ADC_PWM; float temp;//电压值 u8 string[20]; 模块初始化 初始化很常规了,注意PWM使用比较输出。 void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE); GPIO_InitStructure.GPIO_Pin=0xff00; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOD,&GPIO_InitStructure); GPIOC->ODR=0xff00; GPIOD->ODR|=(1<<2); GPIOD->ODR&=~(1<<2); } void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); } void ADC1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); } float ADC_Read(void) { float temp; ADC_SoftwareStartConvCmd(ADC1, ENABLE); Delay_Ms(5); temp=ADC_GetConversionValue(ADC1)*3.3/0xfff; return temp; } void PWM3_OUT(u16 Frequency1,u8 Duty1,u16 Frequency2,u8 Duty2) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_TimeBaseInitStructure.TIM_Period=0xffff; TIM_TimeBaseInitStructure.TIM_Prescaler=71; TIM_TimeBaseInitStructure.TIM_ClockDivision=0x0; TIM_TimeBaseInitStructure.TIM_CounterMode=0x0; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); TIM3_CH1_Fre=1000000/Frequency1; TIM3_CH1_Duty=TIM3_CH1_Fre*Duty1/100; TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_Pulse=TIM3_CH1_Fre; TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OC1Init(TIM3,&TIM_OCInitStructure); TIM3_CH2_Fre=1000000/Frequency2; TIM3_CH2_Duty=TIM3_CH2_Fre*Duty2/100; TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_Pulse=TIM3_CH2_Fre; TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OC2Init(TIM3,&TIM_OCInitStructure); TIM_Cmd(TIM3,ENABLE); TIM_ITConfig(TIM3,TIM_IT_CC1|TIM_IT_CC2,ENABLE); } 按键控制部分 这个按键程序进行了消抖处理。 void KEY_Read(void) { static u8 KEY1_Num=0,KEY2_Num=0,KEY3_Num=0,KEY4_Num=0; if(KEY1==0) { KEY1_Num++; if(KEY1_Num==1) { Set_Flag^=1; LCD_ClearLine(Line1); LCD_ClearLine(Line3); LCD_ClearLine(Line5); } }else{ KEY1_Num=0; } if(KEY2==0) { KEY2_Num++; if(KEY2_Num==1) { if(Set_Flag==1) { biankong1+=10;//PA6占空比手动模式+10 if(biankong1>90) { biankong1=10; } } } }else{ KEY2_Num=0; } if(KEY3==0) { KEY3_Num++; if(KEY3_Num==1) { if(Set_Flag==1) { biankong2+=10;//PA7占空比手动模式+10 if(biankong2>90) { biankong2=10; } } } }else{ KEY3_Num=0; } if(KEY4==0) { KEY4_Num++; if(KEY4_Num==1) { if(Control_Flag==0) { Control_Flag=1; }else if(Control_Flag==1) { Control_Flag=0; } } }else{ KEY4_Num=0; } } 中断函数 #include "stm32f10x_it.h" extern u32 TimingDelay; extern u8 KEY_Flag; extern u8 ADC_Flag; extern u8 Display_Flag; extern u8 LED_Flag; extern u8 Time_Flag; void SysTick_Handler(void) { static u8 Key_Num=0; static u16 ADC_Num=0; static u8 Display_Num=0; static u16 LED_Num=0; static u16 Time_Num=0; TimingDelay--; if(++Key_Num==50) { Key_Num=0; KEY_Flag=1; } if(++ADC_Num==50) { ADC_Num=0; ADC_Flag=1; } if(++Display_Num==50) { Display_Num=0; Display_Flag=1; } if(++LED_Num==1000) { LED_Num=900; LED_Flag=1; } if(++Time_Num==500) { Time_Num=0; Time_Flag=1; } } void TIM3_IRQHandler(void) { u16 capture1; u16 capture2; if(TIM_GetITStatus(TIM3,TIM_IT_CC1)==1) { TIM_ClearITPendingBit(TIM3,TIM_IT_CC1); capture1=TIM_GetCapture1(TIM3); if(TIM3_CH1_Flag==1) { TIM_SetCompare1(TIM3,capture1+TIM3_CH1_Duty); } if(TIM3_CH1_Flag==0) { TIM_SetCompare1(TIM3,capture1+TIM3_CH1_Fre-TIM3_CH1_Duty); } TIM3_CH1_Flag^=1; } if(TIM_GetITStatus(TIM3,TIM_IT_CC2)==1) { TIM_ClearITPendingBit(TIM3,TIM_IT_CC2); capture2=TIM_GetCapture2(TIM3); if(TIM3_CH2_Flag==1) { TIM_SetCompare2(TIM3,capture2+TIM3_CH2_Duty); } if(TIM3_CH2_Flag==0) { TIM_SetCompare2(TIM3,capture2+TIM3_CH2_Fre-TIM3_CH2_Duty); } TIM3_CH2_Flag^=1; } } 主程序 //Main Body int main(void) { STM3210B_LCD_Init(); LCD_Clear(Black); LCD_SetBackColor(Black); LCD_SetTextColor(White); SysTick_Config(SystemCoreClock/1000); LED_Init(); KEY_Init(); ADC1_Init(); PWM3_OUT(10000,zhankong1,5000,zhankong2); while(1) { if(Display_Flag) { if(Set_Flag==0) { sprintf((char*)string," Data"); LCD_DisplayStringLine(Line1,string); sprintf((char*)string," V:%.2fV",temp); LCD_DisplayStringLine(Line3,string); if(Control_Flag==0) { sprintf((char*)string," Mode:AUTO"); }else if(Control_Flag==1) { sprintf((char*)string," Mode:MANU"); } LCD_DisplayStringLine(Line5,string); } if(Set_Flag==1) { sprintf((char*)string," Para"); LCD_DisplayStringLine(Line1,string); sprintf((char*)string," PA6:%d%%",biankong1); LCD_DisplayStringLine(Line3,string); sprintf((char*)string," PA7:%d%%",biankong2); LCD_DisplayStringLine(Line5,string); } } if(ADC_Flag) { ADC_Flag=0; temp=ADC_Read(); ADC_PWM=temp/3.3*100; // 得到自动模式下的PWM占空比 } if(Time_Flag) { Time_Flag=0; if(Control_Flag==0) { PWM3_OUT(10000,ADC_PWM,5000,ADC_PWM); if(temp==3.30) { PWM3_OUT(10000,100,5000,100); } if(temp==0) { PWM3_OUT(10000,0,5000,0); } }else if(Control_Flag==1) { PWM3_OUT(10000,biankong1,5000,biankong2); } } if(KEY_Flag) { KEY_Flag=0; KEY_Read(); } if(LED_Flag) { LED_Flag=0; if(Control_Flag==0) { GPIOC->ODR^=(1<<8); GPIOC->ODR|=(1<<9); GPIOD->ODR|=(1<<2); GPIOD->ODR&=~(1<<2); }else if(Control_Flag==1) { GPIOC->ODR|=(1<<8); GPIOC->ODR^=(1<<9); GPIOD->ODR|=(1<<2); GPIOD->ODR&=~(1<<2); } } } } |
|
|
|
只有小组成员才能发言,加入小组>>
3138 浏览 9 评论
2834 浏览 16 评论
3345 浏览 1 评论
8721 浏览 16 评论
3941 浏览 18 评论
9554浏览 3评论
893浏览 3评论
463浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
461浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2183浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-22 19:21 , Processed in 0.970810 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号