求助!明明一样的代码为啥在第二个里面就进入不了串口3的中断啊。。。

2019-08-14 01:14发布

通过串口3给一个传感器发送一串16进制的命令,然后传感器收到命令后就返回一串16进制数,在第一个代码中是可以收到传感器返回的数据的,为啥在第二个代码中就直接进入不了中断了呢?求大神看下 代码如下(这是可以的代码)

#include "stm32f10x.h"
#include "delay.h"
#include "stdio.h"
#define N 30

/************************************************
ALIENTEK 战舰STM32F103开发板实验0
工程模板
注意,这是手册中的新建工程章节使用的main文件
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/
//重定义printf打印到串口1
#if 1
#pragma import(__use_no_semihosting)            
//??????????                 
struct __FILE
{
        int handle;

};

FILE __stdout;      
//??_sys_exit()??????????   
_sys_exit(int x)
{
        x = x;
}
//???fputc??
int fputc(int ch, FILE *f)
{      
        while((USART1->SR&0X40)==0);//????,??????   
    USART1->DR = (u8) ch;      
        return ch;
}
#endif

u8 i = 0;//总数据计数
u8 j = 0;//抓取数据次数
u8 k;//用来转换浮点数的计数变量
float data_sum = 0;//记录一定次数的数据总值
float data;//压力数据
float data_aver;//数值平均
unsigned char * ptr_data = (unsigned char*)&data;//转化类型,地址存放到ptr_data里面
unsigned char c[4];//用来存放4个字节的16进制数
//unsigned char data_store[N];//用来存放转换成浮点数的数据


void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
         
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//GPIOB时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//使能USART3
        //USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

  //USART1_RX          GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
       
        //USART3_TX   GPIOB10
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB10

  //USART3_RX          GPIOB11初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PA3
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB11

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
       
        //Usart3 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器

   //USART 初始化设置

        USART_InitStructure.USART_BaudRate = bound;//串口波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;//字长为8位数据格式
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
        USART_InitStructure.USART_Parity = USART_Parity_Odd;//校验位
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

  USART_Init(USART1, &USART_InitStructure); //初始化串口1
        USART_Init(USART3, &USART_InitStructure); //初始化串口3
  //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口1接收中断
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口3接收中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1
        USART_Cmd(USART3, ENABLE);                    //使能串口3

}
//串口1中断函数
/*void USART1_IRQHandler(void)
{
        u32 res;
         if(USART_GetITStatus(USART1,USART_IT_RXNE))
{
         
                 res= USART_ReceiveData(USART1);
     if(res != 0x0d && res != 0x0a)  USART_SendData(USART1,res);
         

  }
}*/
//串口3中断函数
void USART3_IRQHandler(void)
{
        unsigned char res;
       
         if(USART_GetITStatus(USART3,USART_IT_RXNE))
{       
       
    res= USART_ReceiveData(USART3);
         //19--22字节是有效数据位,取出后转换成浮点数发送给串口1
          if(i == 19)   c[3] = res;       
          if(i == 20)   c[2] = res;                       
          if(i == 21)   c[1] = res;
          if(i == 22)
                {
                        c[0] = res;
                        //将4个字节的16进制数转换成浮点数
                        for(k = 0; k <= 3;k++)
                 {
                         *(ptr_data + k) = c[k];
                 }
                  printf("%f ",data);
                  data_sum += data;
                  j++;
                }
                if(j == N) //求取平均数
                {
                        data_aver = data_sum/N;
                         printf("已经进入中断 ");
                        printf("30次的平均数值是:%f ",data_aver);
                        j = 0;
                        data_sum = 0;
                }
          if(i == 24) i = 0;
          i++;
}   
}


int main(void)
{       
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
         delay_init();
         uart_init(1200);
         while(1)
         {
                 u8 i;
                 u16 order[] ={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0X82,0xA6,0x7C,0x03,0x14,0x39,0x03,0x00,0x75};
                 
                 for(i = 0;i < 17;i++)
                 {
                        USART_SendData(USART3,order);
                 }
                        delay_ms(500);
         }
        }

(这个代码就进入不了串口3的中断了)

#include "stm32f10x.h"
#include "delay.h"
#include "stdio.h"
#include "math.h"

/************************************************
ALIENTEK 战舰STM32F103开发板实验0
工程模板
注意,这是手册中的新建工程章节使用的main文件
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/


/*串口1连接led液晶板
  *串口2连接P1
  *串口3连接pd
**/

//第一步:重定义printf打印到串口1
//#if 1
//#pragma import(__use_no_semihosting)                           
//struct __FILE
//{
//        int handle;

//};

//FILE __stdout;           
//_sys_exit(int x)
//{
//        x = x;
//}
//int fputc(int ch, FILE *f)
//{      
//        while((USART1->SR&0X40)==0);//????,??????   
//    USART1->DR = (u8) ch;      
//        return ch;
//}
//#endif
#if 1  
#pragma import (__use_no_semihosting_swi)  
/*标准库需要的支持函数,use_no_semihosting_swi以避免使用半主机模式*/  
struct __FILE  
{  
    int handle;  
};  

FILE __stdout;  
FILE __stdin;  
/*重定向Printf函数*/  
int fputc(int ch,FILE *f)  
{  
    return (SendChar(ch));  
}  
/*重定向Scanf函数*/  
int fgetc(FILE *f)  
{  
    return (SendChar(GetKey()));  
    /*调用scanf()在串口中输入数据时,必须以空格结束,否则无法完成发送*/  
}  

void _ttywrch(int ch)  
{  
    SendChar(ch);  
}  

int _ferror(FILE *f) {  
  /* Your implementation of ferror */  
  return EOF;  
}  

//定义_sys_exit()以避免使用半主机模式  
void _sys_exit(int return_code){  
    //x = x;  
label:goto label;  
}  

#endif  
//第二步:给串口1、2、3设置中断
void uart_init(u32 bound)
{
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//GPIOB时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//使能USART2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//使能USART3
        USART_DeInit(USART3);
       
        //USART1_TX   GPIOA.9
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
       
  //USART1_RX          GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10   
       
        //USART2_TX   GPIOA2
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA2

        //USART2_RX          GPIOA3初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA3
       
       
        //USART3_TX   GPIOB10
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB10

        //USART3_RX          GPIOB11初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PA3
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB11

        //Usart1 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
       
        //Usart2 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
       
        //Usart3 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器

   //USART 初始化设置

        USART_InitStructure.USART_BaudRate = bound;//串口波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;//字长为9位数据格式
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
        USART_InitStructure.USART_Parity = USART_Parity_Odd;//校验位
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

   USART_Init(USART1, &USART_InitStructure); //初始化串口1
         USART_Init(USART2, &USART_InitStructure); //初始化串口2
        USART_Init(USART3, &USART_InitStructure); //初始化串口3
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口1接收中断
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口2接收中断
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口3接收中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1
        USART_Cmd(USART2, ENABLE);                    //使能串口2
        USART_Cmd(USART3, ENABLE);                    //使能串口3
}
//第三步:设置全局变量,全都为浮点型
float H1 = 0.1;//上空腔高度
float H2 =0.1 ;//下空腔高度
float H = 0.4;//密度传感器上空腔下表面到下空腔上表面高度

float h1_shift=0;//上偏移
float h2_shift=0;//下偏移
float h1=0;//密度传感器上空腔下表面到河面的距离
float h2=0;//密度传感器下空腔下表面到河面的距离

float p0 = 101325;//标准大气压

float p1=0;//密度传感器上空腔中的水面压强
u8 i=0;//用来记录P1的16进制数的位数
u8 p1_time = 0;//用来记录p1的传过来数据的次数
float p1_sum= 0;//p1一定次数内的总和
float p1_aver=0;//p1一定次数的统计平均
unsigned char *ptr_p1 = (unsigned char *)&p1;//强制转换类型,把p1的地址放入ptr_p1中
unsigned char p1_data[4];//用来存放来自p1的四个16进制字节数


float pd=0;//微差压
u8 j = 0;//用来记录Pd的16进制数的位数
u8 pd_time = 0;//用来记录pd传过来数据的次数
float pd_sum=0;//微差压一定次数的总和
float pd_aver=0;//微差压一定次数的平均
unsigned char *ptr_pd = (unsigned char *)&pd;//强制转换类型,把pd的地址放入ptr_pd中
unsigned char pd_data[4];//用来存放来自pd的四个16进制字节数


float midu= 0;//密度
float m = 0;//含沙量
float pd0 = 0;//水中的微差压
float g = 9.8;//重力加速度
u8 N = 100;//100次取一次均值
u8 k = 0;//用来将十六进制数据转换成浮点数
u8 mode = 1;//设置纯水或者是测沙模式
float h1_shift_water = 0;//纯水中的上偏移
float h2_shift_water = 0;//纯水中的下偏移


//第四步:设置中断函数
//串口1中断函数
void USART1_IRQHandler(void)
{
        unsigned char res = 0;
        if(USART_GetITStatus(USART1,USART_IT_RXNE))
        {
                res = USART_ReceiveData(USART1);

                        if(res != 0x0d && res != 0x0a)  mode = res - 48;
            printf("已经进入串口1的中断,此时模式是mode %d ",mode);
               
       
        }
}
/*void USART2_IRQHandler(void)
{
        unsigned char res;
       
         if(USART_GetITStatus(USART2,USART_IT_RXNE))
{
          
                res= USART_ReceiveData(USART2);
                if(i == 19)   p1_data[3] = res;       
                if(i == 20)   p1_data[2] = res;                       
                if(i == 21)   p1_data[1] = res;
                if(i == 22)
                {
                        p1_data[0] = res;
                        //将4个字节的16进制数转换成浮点数
                        for(k = 0; k <= 3;k++)
                        {
                         *(ptr_p1 + k) = p1_data[k];
                        }
                        p1_sum += p1;
                        p1_time++;
                }
                if(N == p1_time) //达到次数,求取平均数
                {
                        p1_aver = p1_sum/N;//P1是上表面压强
                        p1_time = 0;
                        p1_sum = 0;
                        printf("已经进入串口2的中断 ");
                        //USART_SendData(USART1,p1_aver);
                }
          if(i == 24) i = 0;
          i++;
  }
}*/

//串口3中断函数
//void USART3_IRQHandler(void)
//{
//        unsigned char res;
//       
//       
//         if(USART_GetITStatus(USART3,USART_IT_RXNE))
// {
//         
//                res= USART_ReceiveData(USART2);
//                if(j == 19)   pd_data[3] = res;       
//                if(j == 20)   pd_data[2] = res;                       
//                if(j == 21)   pd_data[1] = res;
//                if(j == 22)
//                {
//                        pd_data[0] = res;
//                        //将4个字节的16进制数转换成浮点数
//                        for(k = 0; k <= 3;k++)
//                        {
//                         *(ptr_pd + k) = pd_data[k];
//                        }
//                        pd_sum += pd;
//                        pd_time++;
//                }
//                if(N == pd_time) //达到次数,求取平均数
//                {
//                        pd_aver = pd_sum/N;
//                        pd_time = 0;
//                        pd_sum = 0;
//                        printf("已经进入串口3的中断 ");
//                        //USART_SendData(USART1,pd_aver);
//                }
//          if(j == 24) j = 0;
//          j++;
//  }
//}
void USART3_IRQHandler(void)
{
        if(USART_GetITStatus(USART3,USART_IT_RXNE))
        {
                printf("进入串口3 ");
        }
}

int main(void)
{       
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
         delay_init();
         uart_init(1200);
         while(1)
         {
                 u8 order_index;
                 u16 order[] ={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0X82,0xA6,0x7C,0x03,0x14,0x39,0x03,0x00,0x75};
                 printf("请选择模式:1.纯水模式2.测沙模式(5s内未选择则默认当前模式,还没有进入中断) ");
                 delay_ms(1200);
                 delay_ms(1200);
                 delay_ms(1200);
                 if(1 == mode )
                 {
                        printf("进入1模式(mode1) ");
                                  //向串口2发送指令,之后会进入中断
                        for(order_index = 0;order_index < 17;order_index++)
                 {
                        USART_SendData(USART2,order[order_index]);
                 }
                        delay_ms(1500);
                         //向串口3发送指令,之后进入串口3中断
                         for(order_index = 0;order_index < 17;order_index++)
                         {
                                USART_SendData(USART3,order[order_index]);
                         }
                                delay_ms(1500);
                         
                         //处理压强,并发送给串口1(led液晶板)
                         
                         if( (p1_aver !=         0) && (pd_aver != 0) )
                         {
                                h1_shift_water = (p1*H1)/(p0 + p1);
                                h2_shift_water = (2*H2+H+h1_shift+p1*H1/(1000*g*h1_shift)- sqrt(((2*H2)+H+h1_shift+p1*H1/(1000*g*h1_shift))*((2*H2)+H+h1_shift+p1*H1/(1000*g*h1_shift))-4*(H+H2+h1_shift+p1/(1000*g))*H2))/2;
                               
                                if(0 == pd0) pd0 = pd_aver;
                                if(0 != pd0) pd0 = (pd0 + pd_aver)/2;
                                printf("%.6f,  上偏移:%.6f, 下偏移:%.6f",pd0,h1_shift,h2_shift );
                                p1_aver = 0;
                                pd_aver = 0;
                         }
                 }
                  if(2 == mode )
                 {
                        printf("进入2模式(mode2) ");
                                  //向串口2发送指令,之后会进入中断
                        for(order_index = 0;order_index < 17;order_index++)
                         {
                                USART_SendData(USART2,order[order_index]);
                         }
                                delay_ms(500);
                         //向串口3发送指令,之后进入串口2中断
                         for(order_index = 0;order_index < 17;order_index++)
                         {
                                USART_SendData(USART3,order[order_index]);
                         }
                                delay_ms(500);
                         
                         //处理压强,并发送给串口1(led液晶板)
                         
                         if( (p1_aver != 0) && (pd_aver != 0) ) //当压强差的平均值和上表面的平均值不是0的时候
                         {
                                h1_shift = (p1*H1)/(p0 + p1);
                                h2_shift = (2*H2+H+h1_shift+p1*H1/(1000*g*h1_shift)- sqrt(((2*H2)+H+h1_shift+p1*H1/(1000*g*h1_shift))*((2*H2)+H+h1_shift+p1*H1/(1000*g*h1_shift))-4*(H+H2+h1_shift+p1/(1000*g))*H2))/2;
                                midu = (1000*g*(h1_shift_water - h2_shift_water + H +H2) + pd -pd0)/(g * (h1_shift -h2_shift +H + H2));
                                 m = (midu-1000)*1000;
                                printf("%.6f",m);
                                p1_aver = 0;
                                pd_aver = 0;
                         }
                 }
         }
        }
串口2还不知道因为暂时只有一个传感器


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
aiyeba
1楼-- · 2019-08-15 00:07
gc475668754 发表于 2017-9-14 20:26
谢谢~~寄存器没怎么看,我去研究下。不过为啥在第一个代码里面就可以呢

寄存器的话,不是叫你用寄存器配置.

而是中断里面用成寄存器的那种试试.
gc475668754
2楼-- · 2019-08-15 05:53
aiyeba 发表于 2017-9-15 09:43
寄存器的话,不是叫你用寄存器配置.

而是中断里面用成寄存器的那种试试.

不太明白呢,,

一周热门 更多>