历史上的今天
今天是:2024年08月23日(星期五)
2019年08月23日 | STM32F407 纯寄存器操作定时器,PWM,ADC(专治花里胡哨)
2019-08-23 来源:eefocus
定时器

真多啊,14个定时器,三种。
通用定时器



注意:
需要手动清除中断标志


TIM3->ARR = 5000-1; //自动重载寄存器,10Khz 的计数频率,计数 5K 次为 500ms
TIM3->PSC = 8400-1; //预分频器
两个寄存器的计算
PSC预分频器
//这里时钟选择为 APB1 的 2 倍,而 APB1 为 42M,所以TIM3的时钟频率为84M

PSC=8400
f=84M/8400=10000Hz=10KHz
t=1/f=0.1ms
每次技术时间0.1ms
ARR=5000-1; //自动重载寄存器
计数5000次,共500ms
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
完整代码
#include #include #include int main() { Stm32_Clock_Init(336,8,2,7); //系统时钟 delay_init(48); SCB->AIRCR = 0x05FA0000 | 0x500; NVIC->IP[29] = 0x50; //最低抢占优先级,最低响应优先级01 01 EXTI2中断 NVIC->ISER[0] |= (1<<29); //使能中断线29,也就是EXTI2中断 RCC->AHB1ENR |= 0x00000020; //使能GPIOF时钟 RCC->APB1ENR |= 1<<1; GPIOF->MODER &= 0x00000000; //设置F9,F10 0001 0100 0000 0000 0000 0000 GPIOF->MODER |= 0x00140000; GPIOF->OTYPER &= 0x00000600; //设置F9,F10推挽输出 GPIOF->OSPEEDR &= 0x00000000; //F9,F10 速度50m 0010 1000 0000 0000 0000 0000 GPIOF->OSPEEDR |= 0x00280000; TIM3->ARR = 5000-1; //10Khz 的计数频率,计数 5K 次为 500ms TIM3->PSC = 8400-1; TIM3->DIER |=1<<0; TIM3->CR1 |= 1<<0; while(1) { GPIOF->BSRRL = 0x0200; //0000 0000 0010; GPIOF->BSRRL = 0x0400; } } void TIM3_IRQHandler() { if(TIM3->SR&0X0001)//溢出中断 { GPIOF->BSRRH = 0x0200; //0000 0000 0010 GPIOF->BSRRH = 0x0400; delay_ms(1000); } TIM3->SR&=~(1<<0);//清除中断标志位 } PWM #include #include #include int main() { u16 dir; u16 led0pwmval; Stm32_Clock_Init(336,8,2,7); //系统时钟 delay_init(48); RCC->APB1ENR|=1<<8; //TIM14 时钟使能 RCC->AHB1ENR|=1<<5; //使能 PORTF 时钟 GPIO_Set(GPIOF,PIN9,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M, GPIO_PUPD_PU);//复用功能,上拉输出 GPIO_AF_Set(GPIOF,9,9); //PF9,AF9 TIM14->ARR=500-1; //设定计数器自动重装值 TIM14->PSC=84-1; //预分频器不分频 TIM14->CCMR1|=6<<4; //CH1 PWM1 模式 TIM14->CCMR1|=1<<3; //CH1 预装载使能 TIM14->CCER|=1<<0; //OC1 输出使能 TIM14->CCER|=1<<1; //OC1 低电平有效 TIM14->CR1|=1<<7; //ARPE 使能 TIM14->CR1|=1<<0; //使能定时器 14 while(1) { delay_ms(10); if(dir)led0pwmval++; else led0pwmval--; if(led0pwmval>300)dir=0; if(led0pwmval==0)dir=1; TIM14->CCR1 =led0pwmval; } } ADC #include #include #include #include void Adc_Init(void); //ADC 初始化 u16 Get_Adc(u8 ch); //获得某个通道值 u16 Get_Adc_Average(u8 ch,u8 times);//得到某个通道给定次数采样的平均值 int main() { u16 adcx; float temp; Stm32_Clock_Init(336,8,2,7); //系统时钟 delay_init(168); uart_init(84,115200); Adc_Init(); //初始化 ADC while(1) { adcx=Get_Adc_Average(5,20); temp=(float)adcx*(3.3/4096); adcx=temp; //整数 printf("%d.",adcx); temp-=adcx; //小数 temp*=1000; printf("%dVn",(u16)temp); delay_ms(1000); } } //初始化 ADC //这里我们仅以规则通道为例 //我们默认仅开启 ADC1_CH5 void Adc_Init(void) { //先初始化 IO 口 RCC->APB2ENR|=1<<8; //使能 ADC1 时钟 RCC->AHB1ENR|=1<<0; //使能 PORTA 时钟 GPIO_Set(GPIOA,PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU); //PA5,模拟输入,下拉 RCC->APB2RSTR|=1<<8; //ADCs 复位 RCC->APB2RSTR&=~(1<<8); //复位结束 ADC->CCR=3<<16; //ADCCLK=PCLK2/4=84/4=21Mhz,ADC 时钟不要超过 36Mhz ADC1->CR1=0; //CR1 设置清零 ADC1->CR2=0; //CR2 设置清零 ADC1->CR1|=0<<24; //12 位模式 ADC1->CR1|=0<<8; //非扫描模式 ADC1->CR2&=~(1<<1); //单次转换模式 ADC1->CR2&=~(1<<11); //右对齐 ADC1->CR2|=0<<28; //软件触发 ADC1->SQR1&=~(0XF<<20); ADC1->SQR1|=0<<20; //1 个转换在规则序列中 也就是只转换规则序列 1 //设置通道 5 的采样时间 ADC1->SMPR2&=~(7<<(3*5)); //通道 5 采样时间清空 ADC1->SMPR2|=7<<(3*5); //通道 5 480 个周期,提高采样时间可以提高精确度 ADC1->CR2|=1<<0; //开启 AD 转换器 } //获得 ADC 值 //ch:通道值 0~16 //返回值:转换结果 u16 Get_Adc(u8 ch) { ADC1->SQR3&=0XFFFFFFE0;//规则序列 1 通道 ch ADC1->SQR3|=ch; //ch:通道值 0~16 ADC1->CR2|=1<<30; //启动规则转换通道 while(!(ADC1->SR&1<<1));//等待转换结束 return ADC1->DR; //返回 adc 值 } //获取通道 ch 的转换值,取 times 次,然后平均 //ch:通道编号 //times:获取次数 //返回值:通道 ch 的 times 次转换结果平均值 u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t temp_val+=Get_Adc(ch); delay_ms(5); } return temp_val/times; }




















史海拾趣
|
发布我的小作品--U盘(实际是SD卡读卡器) ATmega168+PDIUSBD12+SD (内含GCC源码和原理图) 年前里曾在44b0x板子上实现移动硬盘的功能,年后利用在阿莫这买的一片TQFP封装的m168 和一年前在上海赛格买的D12,再加上花15大洋的SD读卡器上的SD插槽。 ...… 查看全部问答> |
|
网友在各自领域中所用到的芯片总结(转载)1.音频pcm编码DA转换芯片cirrus logic的cs4344,cs4334 4334是老封装,据说已经停产,4344封装比较小,非常好用。还有菲利谱的。 8211等。 2.音频放大芯片4558,833,此二芯 ...… 查看全部问答> |
|
我是个初学者,求教高人,都说开关管冲放电斜率越大(即冲放电越快)产生EMI的尖峰越突出,这到底是为什么呢?能不能推荐一些文章或是参考资料?小弟我这几日寝食难安,网上也啥资料找不到,国外的相关文章也很少有讲,真是急死了,在此拜谢!!… 查看全部问答> |
|
在wince下面有一个RotateScreen.exe 系统默认的是横屏,横屏状态下,一切OK。 但是切换到竖屏之后,一般的应用程序也是OK的,但是,像视频播放和一些与Overlay相关的DDraw程序就会运行错误 甚至直接花屏,这个是什么原因啊,这个Rotate在显示驱 ...… 查看全部问答> |
|
最近在调试一块C8051F340为MCU的板子。能够正常工作,并且USB接口也能使用。但是在对XRAM进行操作的时候总是有问题,请教各位uchar xdata *M;M=0xB00;*M=0x01;我使用仿真器单步运行的时候,在memory窗口中看不到0xB00的处的数值变化,这个值总是保 ...… 查看全部问答> |
|
比如我输入i或者符号表中有的函数 就会响应 可是我输入的是一堆乱的字符就会返回undefined symbols 我想知道处理这个过程的函数在内核的哪个库???谢谢啦… 查看全部问答> |




