完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、芯片及开发环境:STM8S003和IAR开发环境;
2、主要问题:程序需实现3.5V以下关机功能,若每12秒未收到串口输入的数据(数据是5秒发一次的字符a),否则闪断关机脚,实现RESET。现在的问题是串口没有中断输入时,可正常检测到3.5V并关机,若串口有数据不断输入时,则3.3V才关机,请问何原因?查到较多关于串口中断,定时器,串口过载错误等资料,一个星期了始终没有解决。项目是一个车载跟踪器的项目,马上要出货了,比较着急,求助大家帮忙看看,谢谢了! 3、main.c完整程序如下: #include unsigned int ADCData; unsigned int second_count; unsigned int uart_count; unsigned char powerflag; #define ONOFF_ON() PC_ODR_bit.ODR7 = 0 #define ONOFF_OFF() PC_ODR_bit.ODR7 = 1 #define MX6_POR_B_ON() PC_ODR_bit.ODR5 = 0 #define MX6_POR_B_OFF() PC_ODR_bit.ODR5 = 1 #define Voltage_3V7 0x02EE //3.75v*22k/(22k+12k)=2.43v(%d0750) #define Voltage_3V5 0x02B8 //3.50v*22k/(22k+12k)=2.26v(%d0696) /******************************************************************************* **函数名称:void delay(unsigned int ms) **功能描述:大概延时 **入口参数:unsigned int ms 输入大概延时数值 **输出:无 *******************************************************************************/ void delay(unsigned int ms) { unsigned int x , y; for(x = ms; x > 0; x--) /*通过一定周期循环进行延时*/ for(y = 1000 ; y > 0 ; y--); } /******************************************************************************* **函数名称:ONOFF_Init() **功能描述:初始化ONOFF引脚 **入口参数:无 **输出:无 *******************************************************************************/ void ONOFF_Init() { PC_DDR_bit.DDR7 = 1; //设置端口PC->7的输入输出方向寄存器为输出方向 PC_CR1_bit.C17 = 1; //PC->7为推挽输出 PC_CR2_bit.C27 = 1; //PC->7是输出速度最快为10MHz } /******************************************************************************* **函数名称:MX6_POR_B_Init() **功能描述:初始化MX6_POR_B控制引脚 **入口参数:无 **输出:无 *******************************************************************************/ void MX6_POR_B_Init() { PC_DDR_bit.DDR5 = 1; //设置端口PC->5的输入输出方向寄存器为输出方向 PC_CR1_bit.C15 = 1; //PC->5为推挽输出 PC_CR2_bit.C25 = 1; //PC->5是输出速度最快为10MHz } /******************************************************************************* **函数名称:void tiM1_Init() **功能描述:定时器1参数初始化 **入口参数:无 **输出:无 *******************************************************************************/ void TIM1_Init() { TIM1_CR1_bit.CEN = 0; //stop tim1 //设置定时器的时钟为 = 16000000 / (psc + 1) = 16000000 / 400 = 40000Hz TIM1_PSCRH = 399 / 256; //设置定时器1的预分频数值为 psc = 399 + 1 TIM1_PSCRL = 399 % 256; // TIM1_CR1_bit.CMS = 0; //设置定时器1的边沿对齐模式 TIM1_CR1_bit.DIR = 0; //计数模式为向上计数 UP Count //设置定时器1计数40000次 = 1秒时间产生中断 TIM1_ARRH = 40000 / 256; //高八位 TIM1_ARRL = 40000 % 256; //低八位 TIM1_CNTRH = 0x0000; //清除计数寄存器的高八位 TIM1_CNTRL = 0x0000; //清除计数寄存器的低八位 TIM1_IER_bit.UIE = 1; //使能更新中断 TIM1_CR1_bit. ARPE = 1; //设置允许自动更新 TIM1_CR1_bit. CEN = 1; //使能定时器1开始计数 } /******************************************************************************* **函数名称:void UART1_Init(unsigned int baudrate) **功能描述:初始化USART模块 **入口参数:unsigned int baudrate -> 设置串口波特率 **输出:无 *******************************************************************************/ void UART1_Init(unsigned int baudrate) { unsigned int baud; baud = 16000000 / baudrate; //设定串口相应波特率与串口时钟的分频数 //先写BRR2 , 再写BRR1 UART1_BRR2 = ((unsigned char)((baud 0xf000) >> 8 )) | ((unsigned char)(baud 0x000f)); //先写波特比率的高4位与低4位 UART1_BRR1 = ((unsigned char)((baud 0x0ff0) >> 4)); //后写波特比率的中间8位 UART1_CR1_bit.UART0 = 0; //使能UART0 UART1_CR2_bit.RIEN = 1; //使能中断接收 UART1_CR2_bit.TEN = 1; //使能发送 UART1_CR2_bit.REN = 1; //接收使能 } /******************************************************************************* **函数名称:void Uart_SendData(unsigned char data) **功能描述:向串口发送寄存器写入一个字节数据 **入口参数:unsigned char data **输出:无 *******************************************************************************/ void Uart_SendData(unsigned char data) { while(!(UART1_SR 0X80)); //判断发送数据寄存器是否为空 UART1_DR = data; //向发送寄存器写入数据 } /******************************************************************************* **函数名称:void ADC_Init() **功能描述:初始化ADC **入口参数:无 **输出:无 *******************************************************************************/ void ADC_Init() { PD_DDR_bit.DDR3 = 0; //设置PD->3 为输入 PD_CR1_bit.C13 = 0; //设置为悬空输入 PD_CR2_bit.C23 = 0; //设置中断禁止 ADC_CR1_bit.SPSEL = 3; //fmaster / 18 = 16MHZ / 18 = 888888HZ ADC_CR2_bit.ALIGN = 1; //RIGHT ALIGN ADC_CSR_bit.CH = 4; //SELECT AIN4 ADC_CR1_bit.ADON = 1; //启动ADC } /******************************************************************************* **函数名称:void ADC_Data_Read(unsigned int *AD_Value) **功能描述:读取ADC完成一次模数转换结果 **入口参数:unsigned int *AD_Value *AD_Value ->读取ADC采样数据的指针 **输出:无 *******************************************************************************/ void ADC_Data_Read(unsigned int *AD_Value) { ADC_CR1_bit.ADON = 1; //启动ADC while(ADC_CSR_bit.EOC == 0); //等待转换结束 *AD_Value = ADC_DRH; //先读取高8位 *AD_Value = (unsigned int)((*AD_Value << 8) + ADC_DRL); //高8位与低8位相加,凑成16位数据 } /******************************************************************************* **函数名称:void IWDG_Init() **功能描述:初始化独立看门狗 **入口参数:无 **输出:无 *******************************************************************************/ void IWDG_init(void) { IWDG_KR = 0xCC; //启动IWDG IWDG_KR = 0x55; //解除 PR 及 RLR 的写保护 IWDG_RLR = 0xFF; //看门狗计数器重装载数值 IWDG_PR = 0x06; //分频系数为256,最长超时时间为:1.02S IWDG_KR = 0xAA; //刷新IDDG,避免产生看门狗复位,同时恢复 PR 及 RLR 的写保护状态 } /******************************************************************************* **函数名称:void Power_Manage() **功能描述:MX6电源控制函数 **入口参数:无 **输出:无 *******************************************************************************/ void Power_Manage(void) { ADC_Data_Read( ADCData); //读取ADC的采样数值 if(ADCData >= Voltage_3V7) //如果电压大于3.7V,则打开MX6电源 { delay(50); //延时去抖动 ADC_Data_Read( ADCData); //读取ADC的采样数值 if(ADCData >= Voltage_3V7) { MX6_POR_B_ON(); //开启MX6电源 powerflag=1; //置MX6电源标志位为1 } } else if((ADCData > 0) (ADCData <= Voltage_3V5)) //如果电压为3.5v以下,关掉MX6电源 { delay(50); //延时去抖动 ADC_Data_Read( ADCData); //读取ADC的采样数值 if((ADCData > 0) (ADCData <= Voltage_3V5)) { MX6_POR_B_OFF(); //关MX6电源 powerflag=0; //置MX6电源标志位为0 } } else {;} delay(50); //延时去抖动 } /* 主函数 */ int main(void) { asm("sim"); //关闭系统总中断 CLK_CKDIVR = 0x00; //CPUDIV = 1 HSIDIV = 1 内部时钟 = 16Mhz UART1_Init(9600); //调用串口初始化函数,并设置波特率为9600 bps TIM1_Init(); //调用定时器1初始化函数 ADC_Init(); //调用ADC初始化函数 ONOFF_Init(); //初始化NOOFF控制引脚 ONOFF_ON(); //默认关闭imx6ul睡眠控制脚 MX6_POR_B_Init(); //初始化MX6_POR_B控制引脚 MX6_POR_B_ON(); //默认开启imx6ul电源 powerflag=1; //清除MX6电源标志位 IWDG_init(); //始化独立看门狗 asm("rim"); //打开系统总中断 while(1) { Power_Manage(); IWDG_KR = 0xAA; //刷新IDDG,避免产生看门狗复位,同时恢复 PR 及 RLR 的写保护状态 } } /******************************************************************************* **函数名称:__interrupt void UART1_RX_RXNE(void) **功能描述:串口接收数据中断服务函数 **入口参数:无 **输出:无 *******************************************************************************/ #pragma vector = 0x14 //设置串口接收中断向量号 = 0X14 __interrupt void UART1_RX_RXNE(void) { unsigned char ch1; UART1_SR_RXNE = 1; //清除中断标志 uart_count++; //中断使 uart_count++++ 做加法,记录产生的中断次数 if(UART1_SR_OR_LHE) //发生过载错误,顺序读UART1_SR,UART1_DR来清UART1_SR_OR_LHE位 { ch1 = UART1_SR; ch1 = UART1_DR; } else { ch1 = UART1_DR; } Uart_SendData(ch1); //把接收到的数据再通过串口发送出去 return; } /******************************************************************************* **函数名称:__interrupt void TIM1_UPDATE_IRQHandler(void) **功能描述:定时器1重载更新中断服务函数 **入口参数:无 **输出:无 *******************************************************************************/ #pragma vector = TIM1_OVR_UIF_vector //设置定时器1重载的中断向量号 = 13 __interrupt void TIM1_UPDATE_IRQHandler(void) { TIM1_SR1_bit.UIF = 0; //清除中断标志 second_count++; //中断使 second_count++ 做加法,记录1秒产生的中断次数 if(second_count >= 12) //记录达到12秒,即12秒(与MX6的kernel启动时间相关) { second_count = 0; //复位记录TIM1中断次数 if((uart_count == 0) (powerflag==1)) { MX6_POR_B_OFF(); //关MX6电源 delay(500); MX6_POR_B_ON(); //打开MX6电源 } else { uart_count = 0; //复位记录串口中断次数 //PC_ODR ^= 0x80; //对LED2进行异或取反,使LED2以1秒的周期亮灭 } } } 现在的问题是没有串口中断输入时,可正常检测到3.5V并关机,若串口有数据不断输入时,则3.3V才关机,请问何原因? |
|
相关推荐
1个回答
|
|
1. 串口中断和定时器配置问题:在您的程序中,可能存在串口中断和定时器配置不当的问题。这可能导致在接收到串口数据时,定时器没有正确地计时,从而影响了关机电压的检测。 2. ADC采样问题:在串口数据不断输入时,可能会影响到ADC的采样。这可能是由于CPU在处理串口中断时占用了大量时间,导致ADC采样时间不足,从而影响了关机电压的检测。 为了解决这个问题,您可以尝试以下方法: 1. 确保串口中断和定时器配置正确。您可以查阅STM8S003的参考手册,了解如何正确配置串口中断和定时器。 2. 在串口中断处理函数中,尽量减少执行的操作,以减少CPU占用时间。这样可以确保ADC有足够的时间进行采样。 3. 考虑使用DMA(Direct Memory Access)来处理串口数据的接收,这样可以减少CPU的占用时间,从而不影响ADC采样。 4. 在ADC采样完成后,立即将采样结果存储在一个变量中,以避免在处理串口中断时被覆盖。 5. 在判断是否需要关机时,使用之前存储的ADC采样结果,而不是实时采样的结果。 6. 如果问题仍然存在,您可以尝试使用一个外部中断来检测电压降低到3.5V的情况,而不是依赖定时器。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1684 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1587 浏览 1 评论
1013 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
706 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1629 浏览 2 评论
1893浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
675浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
538浏览 3评论
558浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
526浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 16:28 , Processed in 0.987767 second(s), Total 81, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号