牛人的STM32学习笔记(寄存器版本)(2)

2019-04-09 23:00

USART1->CR1|=0X200C; //1位停止,无校验位. #ifdef EN_USART1_RX //如果使能了接收 //使能接收中断 USART1->CR1|=1<<8; //PE中断使能 USART1->CR1|=1<<5; //接收缓冲区非空中断使能 MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级 #endif }

void USART1_IRQHandler(void) { u8 res; if(USART1->SR&(1<<5))//接收到数据 { res=USART1->DR; if((USART_RX_STA&0x80)==0)//接收未完成 { if(USART_RX_STA&0x40)//接收到了0x0d { if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x80; //接收完成了 }else //还没收到0X0D { if(res==0x0d)USART_RX_STA|=0x40; else { USART_RX_BUF[USART_RX_STA&0X3F]=res; USART_RX_STA++; if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } }

以上两个函数已经封装在usart.c中可直接调用

三、外部中断

STM32的每一个IO口都可以作为中断输入,要想把IO口作为中断输入则必须将IO口设置成上拉/下拉输入或浮空输入(设置成浮空输入时要接上拉或下拉电阻否则可能导致中断不断触发)。下面总结一下设置IO口为外部中断时的步骤:

(1)将IO口设置成输入模式 这个在第一章总结过,这里不多说。

(2)开启IO口复用时钟,设置IO口与中断线的映射关系

这一步在函数void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 中已经封装好可直接调用这里说一下IO口的复用时钟使能:

15 ADC3EN 7 IOPFEN 14 13 USART1EN TIM8EN 6 5 IOPEEN IOPDEN 12 SPI1EN 4 IOPCEN 11 TIM1EN 3 IOPBEN 10 ADC2EN 2 IOPAEN 9 ADC1EN 1 保留 8 IOPGEN 0 AFIOEN

RCC_APB2ENR RCC_APB2ENR|=0X01; //使能IO口复用时钟

(3)开启与该IO口相对应的线上中断/事件,并设置触发条件

这一步封装在函数void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 中,可以直接调用,例如:Ex_NVIC_Config(GPIO_A,0,RTIR); //设置PA(0)上升沿触发

Ex_NVIC_Config(GPIO_A,13,FTIR);//设置PA(13)下降沿触发 (4)配置中断分组(NVIC)并使能中断

这一步封装在函数void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) 里面可以直接调用,例如:

MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2 这里值得注意的是EXTI0、EXTI1、EXTI2、EXTI3、EXTI4为Line0~Line4 EXTI15_10为Line15~Line10 EXTI9_5为Line9~Line5 (5)编写中断服务函数

例如: void EXTI15_10_IRQHandler(void) {

delay_ms(10); //消抖 if(KEY0==0) //按键0 {

LED0=!LED0; }

else if(KEY1==0)//按键1 {

LED1=!LED1; }

EXTI->PR=1<<13; //清除LINE13上的中断标志位 EXTI->PR=1<<15; //清除LINE15上的中断标志位 }

四、定时计数器中断

STM32共有8个定时计数器,其中TIME1和TIME8是高级定时器,TIME2~TIME5是通用定时器,TIME6和TIME7是基本定时器,这里以TIME3为例先总结以下定时计数器的基本用法。

定时计数器TIME3中断的配置步骤: (1)TIME3时钟使能 31 保留 23 USBEN 15 SPI3EN 7 30 22 I2C2EN 14 SPI2EN 6 保留 29 DACEN 21 I2C1EN 13 28 PWREN 20 UART5EN 12 保留 5 4 TIM7EN TIM6EN 27 26 25 24 BKPEN 保留 CANEN 保留 19 18 17 16 UART4EN UART3EN UART2EN 保留 11 10 9 8 WWDGEN 保留 3 2 1 0 TIM5EN TIM4EN TIM3EN TIM2EN RCC_APB1ENR

例如: RCC->APB1ENR|=1<<1; //使能TIME3的时钟; RCC->APB1ENR|=1<<2; //使能TIME4的时钟; RCC->APB1ENR|=1<<3; //使能TIME5的时钟; RCC->APB1ENR|=0X01;//使能TIME2的时钟使能;(RCC->APB1ENR|=1<<0;) 其余的一次类推。

15 ADC3EN 7 IOPFEN 14 13 USART1EN TIM8EN 6 5 IOPEEN IOPDEN 12 SPI1EN 4 IOPCEN 11 TIM1EN 3 IOPBEN 10 ADC2EN 2 IOPAEN 9 ADC1EN 1 保留 8 IOPGEN 0 AFIOEN RCC_APB2ENR (2)设置TIM3_ARR和TIM3_PSC的值 这两个位分别设置自动重装值及分频系数 15 7 14 6 13 5 12 11 ARR[15:8] 4 3 ARR[7:0] 10 2 9 1 8 0 TIMx_ARR(TIM6和TIM7自动重装载寄存器) 15 7 14 6 13 5 12 11 PSC[15:8] 4 3 PSC[7:0] 10 2 9 1 8 0

TIMx_PSC(TIM6和TIM7预分频器)

(3)设置TIM3_DIER允许更新中断

15 14 保留 TDE 7 6 保留 TIE 13 12 保留 CC4DE 5 4 保留 CC4IE 11 CC3DE 3 CC3IE 10 CC2DE 2 CC2IE 9 CC1DE 1 CC1IE 8 UDE 0 UIE TIMx_DIER 例如:TIM3->DIER|=1<<0; //允许更新中断 TIM3->DIER|=1<<6; //允许触发中断 (4)允许TIM3工作(使能TIM3)

15 7 ARPE 14 6 CMS[1:0] 13 12 保留 5 4 DIR 11 3 OPM 10 2 URS 9 8 CKD[1:0] 1 0 UDIS CEN

TIMx_CR1 例如:TIM3->CR1|=0x01; //使能定时器3 15 7 BIF 14 保留 6 TIF 13 5 COMIF 12 CC4OF 4 CC4IF 11 CC3OF 3 CC3IF 10 CC2OF 2 CC2IF 9 CC1OF 1 CC1IF 8 保留 0 UIF

TIMx_SR

该寄存器用来标记当前预定时器相关的各种事件/中断是否发生。 UIF:更新中断标记,当产生更新事件时该位由硬件置’1’。 例如:if(TIM3->SR&0X0001)//溢出中断 (5)TIM3中断分组设置

例如:MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2 直接调用该函数就行 (6)编写中断服务程序

例如:void TIM3_IRQHandler(void) { if(TIM3->SR&0X0001)//溢出中断 {

LED1=!LED1; }

TIM3->SR&=~(1<<0);//清除中断标志位 }

参考程序: void Timerx_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<1;//TIM3时钟使能 TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms

TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟 //这两个东东要同时设置才可以使用中断 TIM3->DIER|=1<<0; //允许更新中断 TIM3->DIER|=1<<6; //允许触发中断 TIM3->CR1|=0x01; //使能定时器3 MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2 }

TIME2的CH2模式2的PWM输出:

脉冲宽度调制模式可以产生一个由寄存器TIMx_ARR确定频率和由寄存器TIMx_CCRx确定其占空比的PWM波形;

使能定时器:RCC->APB1ENR|=1<<0;//使能TIME2的时钟

选择通道(共4个通道):在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2); 15 OC2CE 7 OC1CE 14 13 OC2M[2:0] IC2F[3:0] 6 5 OC1M[2:0] IC1F[3:0] 12 4 11 10 OC2PE OC2FE IC2PSC[1:0] 3 2 OC1PE OC1FE IC1PSC[1:0] 9 8 CC2S[1:0] 1 0 CC1S[1:0] TIMx_CCMR1(捕获/比较模式寄存器1) TIM2->CCMR1|=7<<12; //选择PWM模式2

使能预装载寄存器:必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器; 15 OC2CE 7 OC1CE 14 13 OC2M[2:0] IC2F[3:0] 6 5 OC1M[2:0] IC1F[3:0] 12 4 11 10 OC2PE OC2FE IC2PSC[1:0] 3 2 OC1PE OC1FE IC1PSC[1:0] 9 8 CC2S[1:0] 1 0 CC1S[1:0]

TIMx_CCMR1(捕获/比较模式寄存器1) TIM2->CCMR1|=1<<11; //使能预装载寄存器

使能自动重装载的预装载寄存器:最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器;

15 7 ARPE 14 6 CMS[1:0] 13 12 保留 5 4 DIR 11 3 OPM 10 2 URS 9 8 CKD[1:0] 1 0 UDIS CEN

TIMx_CR1

TIMx_CR1|=1<<7; //使能自动装载的预分频寄存器

设置极性:OCx的极性可以通过软件在TIMx_CCER寄存器中的CCxP位设置,它可以设置为高电平有效或低电平有效。TIMx_CCER寄存器中的CCxE位控制OCx输出使能;


牛人的STM32学习笔记(寄存器版本)(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:罗代黑猪种质资源保护及繁育项目可行性研究报告 - 图文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: