通过串口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还不知道因为暂时只有一个传感器
寄存器的话,不是叫你用寄存器配置.
而是中断里面用成寄存器的那种试试.
一周热门 更多>