STM32单个定时器四通道输入捕获

发布者:CW13236066525最新更新时间:2019-03-06 来源: eefocus关键字:STM32  定时器  输入捕获 手机看文章 扫描二维码
随时随地手机看文章

       以前就纠结过能不能一个定时器进行多路的输入捕获,因为毕竟输出四路的PWM是轻松随意的,当时大概想了一下觉得可能会比较麻烦就一直没去尝试,最近组里的同学做方波测频和测占空比遇到了问题,又提到了这个,今天仔细想了一下有了思路就写程序然后上板子试了一下,解决了这个问题。


       首先我们先看单路的输入捕获是怎么实现的

       定时器的初始化函数:

//定时器2通道1输入捕获配置

//arr:自动重装值

//psc:时钟预分频数

void TIM2_Cap_Init(u16 arr,u16 psc)

{  

RCC->APB1ENR|=1<<0;    //TIM2 时钟使能 

RCC->APB2ENR|=1<<2;    //使能PORTA时钟  

 

GPIOA->CRL&=0XFFFFFFF0; //PA0 清除之前设置  

GPIOA->CRL|=0X00000008; //PA0 输入   

GPIOA->ODR|=0<<0; //PA0 下拉

  

  TIM2->ARR=arr;  //设定计数器自动重装值   

TIM2->PSC=psc;  //预分频器 

 

TIM2->CCMR1|=1<<0; //CC1S=01 选择输入端 IC1映射到TI1上

  TIM2->CCMR1|=1<<4; //IC1F=0001 配置输入滤波器 以Fck_int采样,2个事件后有效

  TIM2->CCMR1|=0<<10; //IC2PS=00 配置输入分频,不分频 

 

TIM2->CCER|=0<<1; //CC1P=0 上升沿捕获

TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中

 

TIM2->DIER|=1<<1;    //允许捕获中断

TIM2->DIER|=1<<0;    //允许更新中断

TIM2->CR1|=0x01;    //使能定时器2

MY_NVIC_Init(2,0,TIM2_IRQn,2);//抢占2,子优先级0,组2    

}

    输入捕获的中断函数:

//捕获状态

//[7]:0,没有成功的捕获;1,成功捕获到一次.

//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.

//[5:0]:捕获高电平后溢出的次数

u8  TIM2CH1_CAPTURE_STA=0;             //输入捕获状态    

u16 TIM2CH1_CAPTURE_VAL;             //输入捕获值

//定时器2中断服务程序  

void TIM2_IRQHandler(void)

{     

u16 tsr;

tsr=TIM2->SR;

  if((TIM2CH1_CAPTURE_STA&0X80)==0)    //还未成功捕获

{

if(tsr&0X01)//溢出

{     

if(TIM2CH1_CAPTURE_STA&0X40)    //已经捕获到高电平了

{

if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)  //高电平太长了

{

TIM2CH1_CAPTURE_STA|=0X80;        //标记成功捕获了一次

TIM2CH1_CAPTURE_VAL=0XFFFF;

}else TIM2CH1_CAPTURE_STA++;

}  

}

if(tsr&0x02)//捕获1发生捕获事件

{

if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿

{  

TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽

    TIM2CH1_CAPTURE_VAL=TIM2->CCR1; //获取当前的捕获值.

TIM2->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获

}else  //还未开始,第一次捕获上升沿

TIM2CH1_CAPTURE_VAL=0;

TIM2CH1_CAPTURE_STA=0X40; //标记捕获到了上升沿

TIM2->CNT=0; //计数器清空

TIM2->CCER|=1<<1; //CC1P=1 设置为下降沿捕获 

}     

}              

  }

TIM2->SR=0;//清除中断标志位     

}

    主函数读取并显示:

int main(void)

{  

u32 temp=0; 

  Stm32_Clock_Init(9); //系统时钟设置

uart_init(72,9600); //串口初始化为9600

delay_init(72);     //延时初始化 

LED_Init();   //初始化与LED连接的硬件接口

  TIM1_PWM_Init(899,36-1); //不分频。PWM频率=72000/(899+1)=80Khz

  TIM2_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 

    while(1)

{

  delay_ms(10);

LED0_PWM_VAL++;

if(LED0_PWM_VAL==300)LED0_PWM_VAL=0;  

if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平

{

temp=TIM2CH1_CAPTURE_STA&0X3F;

temp*=65536; //溢出时间总和

temp+=TIM2CH1_CAPTURE_VAL; //得到总的高电平时间

printf("HIGH:%d us\r\n",temp); //打印总的高点平时间

  TIM2CH1_CAPTURE_STA=0; //开启下一次捕获

  }

}

}

    具体的原理我就不细说了,如果不了解可以去找一下原子的教程,那里面讲得是很详细的,要实现四通道的输入捕获初始化是肯定要修改的,但是最为重要的是修改中断函数中的内容。

    在单路输出中,中断的执行流程是,当新开始一次捕获并且捕获到高电平(就是上升沿),将TIM2->CNT寄存器置0,并且将捕获电平变为低电平(去捕获下降沿),表示新开始一次捕获,然后如果持续高电平使定时器溢出,TIMCH1_CAPTURE_STA会自增1,然后捕获到下降沿以后就完成了一次捕获,这时去读取当前CCR寄存器的值,然后在加上溢出次数*65536得到的就是整个高电平器件定时器总计数值,通过计算计数频率就可以得到高脉冲的时间。

    四通道输入捕获原理

    要实现四路的输入捕获如果每开始一次新的捕获就将CNT值置零是肯定不可以的,一个定时器只有一个CNT寄存器这样会是捕获完全混乱,所以,我的解决方法是:用一个变量Date1来存当开始一次新的捕获时CNT寄存器的值,然后中间步骤和单通道是完全相同的,完成捕获后将那时CCR寄存器的值写到Date2。计算总计数值就是溢出次数*65536+Date2-Date1

    四路输入捕获初始化函数

    注意:我这里将TIM2进行了部分重映射,在不进行重映射的情况下(PA0,PA1,PA2,PA3)通道四无法触发捕获中断)进行部分重映射(PA0,PA1,PB10,PB11)后就可以正常使用,我觉得可能是板子的问题

//定时器2通道1-4输入捕获配置

//arr:自动重装值

//psc:时钟预分频数

void TIM2_Cap_Init(u16 arr,u16 psc)

{  

RCC->APB1ENR|=1<<0;    //TIM2 时钟使能 

RCC->APB2ENR|=1<<2;    //使能PORTA时钟  

RCC->APB2ENR|=1<<3;    //使能PORTB时钟  


RCC->APB2ENR|=1<<0; //AFIO时钟使能

AFIO->MAPR|=2<<8; //TIM2部分映射


GPIOA->CRL&=0XFFFFFF00; //PA0,PA1清除之前设置  

GPIOA->CRL|=0X00000088; //PA0,PA1输入  

GPIOA->ODR|=0<<1; //PA0,PA1下拉

GPIOB->CRH&=0xFFFF00FF; //PB10,PB11清除之前设置

GPIOB->CRH|=0x00008800; //PB10,PB11输入

GPIOB->ODR|=0<<11; //PB10,PB11下拉

  TIM2->ARR=arr;  //设定计数器自动重装值   

TIM2->PSC=psc;  //预分频器 

//CH1

TIM2->CCMR1|=1<<0; //CC1S=01 选择输入端 IC1映射到TI1上

  TIM2->CCMR1|=1<<4; //IC1F=0001 配置输入滤波器 以Fck_int采样,2个事件后有效

  TIM2->CCMR1|=0<<2; //IC1PS=00 配置输入分频,不分频 

TIM2->CCER|=0<<1; //CC1P=0 上升沿捕获

TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中

//CH2

TIM2->CCMR1|=1<<8; //CC2S=01 选择输入端 IC1映射到TI1上

  TIM2->CCMR1|=1<<12; //IC2F=0001 配置输入滤波器 以Fck_int采样,2个事件后有效

  TIM2->CCMR1|=0<<10; //IC2PS=00 配置输入分频,不分频 

TIM2->CCER|=0<<5; //CC2P=0 上升沿捕获

TIM2->CCER|=1<<4; //CC2E=1 允许捕获计数器的值到捕获寄存器中

//CH3

TIM2->CCMR2|=1<<0; //CC3S=01 选择输入端 IC1映射到TI1上

  TIM2->CCMR2|=1<<4; //IC3F=0001 配置输入滤波器 以Fck_int采样,2个事件后有效

  TIM2->CCMR2|=0<<2; //IC3PS=00 配置输入分频,不分频 

TIM2->CCER|=0<<9; //CC3P=0 上升沿捕获

TIM2->CCER|=1<<8; //CC3E=1 允许捕获计数器的值到捕获寄存器中

//CH4

TIM2->CCMR2|=1<<8; //CC4S=01 选择输入端 IC1映射到TI1上

  TIM2->CCMR2|=1<<12; //IC4F=0001 配置输入滤波器 以Fck_int采样,2个事件后有效

  TIM2->CCMR2|=0<<10; //IC4PS=00 配置输入分频,不分频

TIM2->CCER|=0<<13; //CC4P=0 上升沿捕获

TIM2->CCER|=1<<12; //CC4E=1 允许捕获计数器的值到捕获寄存器中


 

//中断使能

TIM2->DIER|=1<<1;    //允许捕获1中断

TIM2->DIER|=1<<2;    //允许捕获2中断

TIM2->DIER|=1<<3;    //允许捕获3中断

TIM2->DIER|=1<<4;    //允许捕获4中断


TIM2->DIER|=1<<0;    //允许更新中断

TIM2->CR1|=0x01;    //使能定时器2

MY_NVIC_Init(2,0,TIM2_IRQn,2);//抢占2,子优先级0,组2    

}

    中断服务函数:

//捕获状态

//[7]:0,没有成功的捕获;1,成功捕获到一次.

//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.

//[5:0]:捕获高电平后溢出的次数

//CH1

u8  TIM2CH1_CAPTURE_STA=0; //输入捕获状态    

u16 TIM2CH1_CAPTURE_Date2; //数据2

u16 TIM2CH1_CAPTURE_Date1; //数据1

//CH2

u8  TIM2CH2_CAPTURE_STA=0; //输入捕获状态    

u16 TIM2CH2_CAPTURE_Date2; //数据2

u16 TIM2CH2_CAPTURE_Date1; //数据1

//CH3

u8  TIM2CH3_CAPTURE_STA=0; //输入捕获状态    

u16 TIM2CH3_CAPTURE_Date2; //数据2

u16 TIM2CH3_CAPTURE_Date1; //数据1

//CH4

u8  TIM2CH4_CAPTURE_STA=0; //输入捕获状态    

u16 TIM2CH4_CAPTURE_Date2; //数据2

u16 TIM2CH4_CAPTURE_Date1; //数据1

 

//定时器2中断服务程序  

void TIM2_IRQHandler(void)

{     

u16 tsr;

tsr=TIM2->SR;

//CH1中断处理

  if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获

{

if(tsr&0X01)//溢出

{     

if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了

{

if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了

{

TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次

TIM2CH1_CAPTURE_Date2=0XFFFF;

}else TIM2CH1_CAPTURE_STA++;

}  

}

if(tsr&0x02)//捕获1发生捕获事件

{

if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿

{  

TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽

    TIM2CH1_CAPTURE_Date2=TIM2->CCR1; //获取当前的捕获值.

TIM2->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获

}else  //还未开始,第一次捕获上升沿

TIM2CH1_CAPTURE_Date2=0;

TIM2CH1_CAPTURE_STA=0X40; //标记捕获到了上升沿

TIM2CH1_CAPTURE_Date1=TIM2->CCR1;

TIM2->CCER|=1<<1; //CC1P=1 设置为下降沿捕获 

}     

}              

  }

//CH2中断处理

if((TIM2CH2_CAPTURE_STA&0X80)==0)//还未成功捕获

{

if(tsr&0X01)//溢出

{     

if(TIM2CH2_CAPTURE_STA&0X40)//已经捕获到高电平了

{

if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了

{

TIM2CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次

TIM2CH2_CAPTURE_Date2=0XFFFF;

}else TIM2CH2_CAPTURE_STA++;

}  

}

if(tsr&0x04)//捕获1发生捕获事件

{

if(TIM2CH2_CAPTURE_STA&0X40) //捕获到一个下降沿

{  

TIM2CH2_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽

    TIM2CH2_CAPTURE_Date2=TIM2->CCR2; //获取当前的捕获值.

TIM2->CCER&=~(1<<5); //CC1P=0 设置为上升沿捕获

}else  //还未开始,第一次捕获上升沿

TIM2CH2_CAPTURE_Date2=0;

TIM2CH2_CAPTURE_STA=0X40; //标记捕获到了上升沿

TIM2CH2_CAPTURE_Date1=TIM2->CCR2;

TIM2->CCER|=1<<5; //CC1P=1 设置为下降沿捕获 

}     

}              

  }

//CH3中断处理

if((TIM2CH3_CAPTURE_STA&0X80)==0)//还未成功捕获

{

if(tsr&0X01)//溢出

{     

if(TIM2CH3_CAPTURE_STA&0X40)//已经捕获到高电平了

{

if((TIM2CH3_CAPTURE_STA&0X3F)==0X3F)//高电平太长了

{

TIM2CH3_CAPTURE_STA|=0X80;//标记成功捕获了一次

TIM2CH3_CAPTURE_Date2=0XFFFF;

}else TIM2CH3_CAPTURE_STA++;

}  

}

if(tsr&0x08)//捕获1发生捕获事件

{

if(TIM2CH3_CAPTURE_STA&0X40) //捕获到一个下降沿

{  

TIM2CH3_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽

    TIM2CH3_CAPTURE_Date2=TIM2->CCR3; //获取当前的捕获值.

TIM2->CCER&=~(1<<9); //CC1P=0 设置为上升沿捕获

}else  //还未开始,第一次捕获上升沿

TIM2CH3_CAPTURE_Date2=0;

TIM2CH3_CAPTURE_STA=0X40; //标记捕获到了上升沿

TIM2CH3_CAPTURE_Date1=TIM2->CCR3;

TIM2->CCER|=1<<9; //CC1P=1 设置为下降沿捕获 

}     

}              

  }

//CH4中断处理

if((TIM2CH4_CAPTURE_STA&0X80)==0)//还未成功捕获

{

if(tsr&0X01)//溢出

{  

if(TIM2CH4_CAPTURE_STA&0X40)//已经捕获到高电平了

{

if((TIM2CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了

{

TIM2CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次

TIM2CH4_CAPTURE_Date2=0XFFFF;

}else TIM2CH4_CAPTURE_STA++;

}  

}

if(tsr&0x10)//捕获1发生捕获事件

{

if(TIM2CH4_CAPTURE_STA&0X40) //捕获到一个下降沿

{  

TIM2CH4_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽

    TIM2CH4_CAPTURE_Date2=TIM2->CCR4; //获取当前的捕获值.

TIM2->CCER&=~(1<<13); //CC1P=0 设置为上升沿捕获

}else  //还未开始,第一次捕获上升沿

TIM2CH4_CAPTURE_Date2=0;

TIM2CH4_CAPTURE_STA=0X40; //标记捕获到了上升沿

TIM2CH4_CAPTURE_Date1=TIM2->CCR4;

TIM2->CCER|=1<<13; //CC1P=1 设置为下降沿捕获 

}     

}              

  }



TIM2->SR=0;//清除中断标志位     

}

       主函数(显示四路信号高点平的时间):

int main(void)

{

u32 temp1=0,temp2=0,temp3=0,temp4=0;

Stm32_Clock_Init(9);   //初始化系统时钟

delay_init(72); //初始化延时

uart_init(72,115200); //串口初始化

TIM1_PWM_Init(1000-1,36-1); //不分频。PWM频率=72000/(899+1)=80Khz

TIM2_Cap_Init(0XFFFF,72-1); //以2Mhz的频率计数 

LED_Init();

TIM1_CH1_PWM_VAL=100;

while(1)  

  {  

if(TIM2CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平

{

temp1=TIM2CH1_CAPTURE_STA&0X3F;

temp1*=65536; //溢出时间总和

temp1+=TIM2CH1_CAPTURE_Date2;

temp1-=TIM2CH1_CAPTURE_Date1; //得到总的高电平时间

printf("TIM2_CH1_HIGH:%d us\r\n",temp1); //打印总的高点平时间

TIM2CH1_CAPTURE_Date1=0;

  TIM2CH1_CAPTURE_STA=0; //开启下一次捕获

  }

if(TIM2CH2_CAPTURE_STA&0X80) //成功捕获到了一次高电平

{

temp2=TIM2CH2_CAPTURE_STA&0X3F;

temp2*=65536; //溢出时间总和

temp2+=TIM2CH2_CAPTURE_Date2;

temp2-=TIM2CH2_CAPTURE_Date1; //得到总的高电平时间

printf("TIM2_CH2_HIGH:%d us\r\n",temp2); //打印总的高点平时间

TIM2CH2_CAPTURE_Date1=0;

  TIM2CH2_CAPTURE_STA=0; //开启下一次捕获

  }

if(TIM2CH3_CAPTURE_STA&0X80) //成功捕获到了一次高电平

{

temp3=TIM2CH3_CAPTURE_STA&0X3F;

temp3*=65536; //溢出时间总和

temp3+=TIM2CH3_CAPTURE_Date2;

temp3-=TIM2CH3_CAPTURE_Date1; //得到总的高电平时间

printf("TIM2_CH3_HIGH:%d us\r\n",temp3); //打印总的高点平时间

TIM2CH3_CAPTURE_Date1=0;

  TIM2CH3_CAPTURE_STA=0; //开启下一次捕获

}

if(TIM2CH4_CAPTURE_STA&0X80) //成功捕获到了一次高电平

{

temp4=TIM2CH4_CAPTURE_STA&0X3F;

temp4*=65536; //溢出时间总和

temp4+=TIM2CH4_CAPTURE_Date2;

temp4-=TIM2CH4_CAPTURE_Date1; //得到总的高电平时间

printf("TIM2_CH4_HIGH:%d us\r\n",temp4); //打印总的高点平时间

TIM2CH4_CAPTURE_Date1=0;

  TIM2CH4_CAPTURE_STA=0; //开启下一次捕获

}

printf("\r\n");

LED=!LED;

delay_ms(10);

  }  

}

 

关键字:STM32  定时器  输入捕获 引用地址:STM32单个定时器四通道输入捕获

上一篇:关于STM32F103C8T6内部FLASH容量的问题
下一篇:错误解决:STM32F103串口1与串口3相同代码却结果不同

推荐阅读最新更新时间:2024-03-16 16:24

关于在Ubuntu下开发STM32程序printf函数的重映射问题
最近使用STM32CubeMX加Ubuntu18.0来进行STM32相关程序的开发,在使用串口打印的使用出现了如下问题: printf函数按照Keil中的方式进行映射后,在软件仍然无法正常使用Printf函数 使用了__io_putchar() 和 int putc()都无法解决问题 我是使用的时makefile项目来通过命令行进行编译的,在网上查了,并且亲自测试后得出结论,在STM32CubeMX生成的makefile项目文件缺少syscalls.c文件,进一步查询发现这个主要是进行系统调用的。结合其中的函数,在使用int __io_putchar(int ch)进行printf重映射的时候还需加入系统调用的相关函数,如
[单片机]
关于在Ubuntu下开发<font color='red'>STM32</font>程序printf函数的重映射问题
stm32中flash的写入与读取
stm32中flash应用的常见函数: 1.擦除函数: FLASH_Status FLASH_ErasePage(u32 Page_Address)只要()里面的数是flash第xx页中对应的任何一个地址!就是擦除xx页全部内容。 2.flash写入函数: STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite) 入参: WriteAddr:要写入flash中的首地址,stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同,因此从理论上来说该地址可以
[单片机]
STM32单片机上RGB数据转为JPEG格式办法
【1】项目背景 在STM32单片机上调用OV系列摄像头读取实时视频,然后对数据进行分析,分析之后再通过WIFI或者4G网络传输给服务器保存和显示。因为处理数据时,采用的是RGB源数据格式,处理之后的 数据需要通过网络传输,由于RGB源数据占用内存很大,对接下来的网络传输非常不力,严重影响传输速度。所以,需要先将RGB数据压缩成JPG格式再进行传输。 【2】常用的JPGE压缩库 (1)libjpeg库 libjpeg是一个用于处理JPEG图像格式的库。它提供了一组用于压缩和解压缩JPEG图像的函数,可以在各种操作系统上使用。libjpeg是由Independent JPEG Group开发的自由软件,其主要功能包括压缩和解压缩J
[单片机]
毕业设计| STM32家庭健康监测系统
系统框架 系统可以实时监测被测者的心率、体温以及周遭环境的温度,也同时可以通过姿态解算来判断被测者是否摔倒。该系统可以将被测者的心率、体温等数据既在本地显示,也可以通过WI-FI传输至云平台以实现远程显示。当被测者摔倒时会发出蜂鸣声,以便引起周围人向被测者施以援手;当被测者吸烟时则会发出警报直至香烟熄灭,可以让被测者远离不健康的生活习惯。 功能简介 该设计主要功能如下: 1) 实时的采集心率、温度、烟雾浓度等信息; 2) 实时的显示心电图以及温度数值信息; 3) 实现跌倒的判断,并且在跌倒时发出报警; 4) 实现吸烟警告,在吸烟时发出报警; 5) 实现将温度、心率、姿态解算数据、烟雾浓度等发送至云平台; 6) 通过登录云平
[单片机]
毕业设计| <font color='red'>STM32</font>家庭健康监测系统
STM32通过USB实现Bootloader/IAP功能
前沿: 最近在做STM32的USB Bootlader/IAP功能,也就是通过USB实现固件升级,本文介绍下实现的基本思路,希望对实现IAP的同学一个参考,改方法已经在产品中得到实际应用并验证是比较合理,稳定可靠的。 程序空间划分: 在单片机的程序Flash中分两个区,分别存储Bootloader代码和App代码,Bootloader放到代码起始地址,也就是0x08000000,App放到0x8020000地址,中间预留了很多的地址空间,主要是为了用来存储一些需要掉电保存的数据,比如我在0x0800C000地址就存放了App程序运行后写入该地址的标志数据。 启动流程: 上电后自然是运行Bootloader程序,Bootloader
[单片机]
<font color='red'>STM32</font>通过USB实现Bootloader/IAP功能
STM32->UART
在使用STM32过程中,可能会因为没有定义好调试工具的连接管脚,例如JTAG和SW需要的管脚被程序重新初始化复用了,然后就没法调试变砖了,此时可以通过ISP的方式擦写flash,或者跳线重启,进入BootLoader模式用JLink下载新的程序或直接擦除MCU的flash,再把跳线改回来重启。 通过串口printf打印输出,添加C语言标准库文件: #include stdio.h 根据编译器定义改写相关函数 #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int
[单片机]
STM32 配置PC13~PC15
在STM32的数据手册的管脚分配图中可以看到:PC14与OSC32_IN公用一个引脚,PC15与OSC32_OUT公用一个引脚,它们的使用方法如下: 当LSE(低速外部时钟信号)开启时,这两个公用管脚的功能是OSC32_IN和OSC32_OUT。 当LSE(低速外部时钟信号)关闭时这两个公用管脚的功能是PC14和PC15。 备用区域控制寄存器(RCC_BDCR)的LSEON用于控制LSE的开启或关闭。关于这个寄存器的用法请参看《STM3210x技术参考手册》。 文档下面有一段话: PC13,PC14和PC15引脚通过电源开关进行供电,因此这三个引脚作为输出引脚时有以下限制: 作为输出脚时只能工作在2MHz模式
[单片机]
<font color='red'>STM32</font> 配置PC13~PC15
基于STM32单片机的电子称设计
摘要 电子秤是将检测与转换技术、计算机技术、信息处理、数字技术等技术综合一体的现代新型称重仪器。它与我们日常生活紧密结合息息相关。 电子称主要以单片机作为中心控制单元,通过称重传感器进行模数转换单元,在配以键盘、显示电路及强大软件来组成。电子称不但计量准确、快速方便,更重要的自动称重、数字显示,对人们生活的影响越来越大,广受欢迎。 本系统的设计主要从硬件电路设计,软件编程调试,实物焊接调试三部分进行详细阐述。硬件电路主要是基于单片机为核心的控制单元实现数据的处理,采用压力传感器对数据进行采集,电子秤专用24位AD转换芯片HX711对传感器采集到的模拟量进行AD转换,转换后的数据送到单片机进行处理显示,数据显示由LCD160
[单片机]
基于<font color='red'>STM32</font>单片机的电子称设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved