您的位置:首页 > 其它

STM32使用串口中断发送和接受数据

2014-12-24 15:07 1046 查看
这里用到的芯片为STM32F103,使用中断进行串口的接受和发送数据。

这里使用直接操作寄存器的方式,使用库函数和这个类似,只是改为调用响应的库函数即可。

配置串口和复用的IO口

void uart_init(u32 pclk2,u32 bound)

{

float temp;

u16 mantissa;

u16 fraction;

temp=(float)(pclk2*1000000)/(bound*16);//分频

mantissa=temp; //分频得到的整数部分

fraction=(temp-mantissa)*16; //小数部分

mantissa<<=4;

mantissa+=fraction;

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

RCC->APB2ENR|=1<<14; //使能串口1的时钟

RCC->APB2ENR|=1<<0; //(+)Alternate function I/O clock enable 好像不要也行,是不是默认是使能的?

GPIOA->CRH&=0XFFFFF00F;//IO对应位清零

GPIOA->CRH|=0X000008B0;//IO状态设置

RCC->APB2RSTR|=1<<14; //复位串口1

RCC->APB2RSTR&=~(1<<14);//停止复位

USART1->BRR=mantissa;//设置波特率

USART1->CR1|=0X200C; //1位停止位,无校验位

//使能发送中断

USART1->CR1|=1<<6;

USART1->SR&=(~(1<<6));//清除中断标志位

//使能接收终端

USART1->CR1|=1<<8; //PE中断使能?

USART1->CR1|=1<<5; //接收缓冲区非空中断使能

MY_NVIC_Init(3,3,USART1_IRQn,2);//第二组中断,最低优先级

}

void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)

{

u32 temp;

MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组

temp=NVIC_PreemptionPriority<<(4-NVIC_Group);

temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);

temp&=0xf;//取低四位

if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位

else NVIC->ISER[1]|=1<<(NVIC_Channel-32);

NVIC->IP[NVIC_Channel]|=temp<<4;//设置响应优先级和抢断优先级

}

//发送中断设置

void USART_SendXByte(USART_TypeDef* USARTx, u16 SendByteNum)

{

HAVE_SEND_LEN=0;//清零已发数据长度标记(全局变量)

ALL_SEND_LEN=SendByteNum;//ALL_SEND_LEN为这一次需要发送的数据长度

IsSending=1;

USART1->DR=SEND_BUF[HAVE_SEND_LEN];

HAVE_SEND_LEN++;

}

中断处理函数

u16 USART_RX_STA=0; //用于标记接收到了一位数据

//u16 USART_SEND_COMPLETE=1; //发送完成标记

u8 REC;//用于接收串口收到的一个字节的数据,全局变量,在其他程序中读这个变量即可取出串口所接收的数据

u16 HAVE_SEND_LEN=0;

u16 ALL_SEND_LEN=0;

char SEND_BUF[USART_SEND_LEN];//未用

char REC_BUF[USART_REC_LEN];//未用

void USART1_IRQHandler(void)

{

if(USART1->SR&(1<<5))//接收到数据

{

USART_RX_STA=1;//置标记位,读取此标记位为真,则读取REC即可取出接收的数据

CountReciByte++;

REC=USART1->DR;

}

if(USART1->SR&(1<<6))//(+)·发送一个字节完成中断

{

if(HAVE_SEND_LEN<ALL_SEND_LEN)

{

USART1->DR=SEND_BUF[HAVE_SEND_LEN];//SEND_BUF[]为全局变量,存放要发送的数据

HAVE_SEND_LEN++;

}

if(HAVE_SEND_LEN==ALL_SEND_LEN)

{

USART_SEND_COMPLETE=1;

while(!(USART1->SR&(1<<6)))

{

//等待最后一个字节发送完成

}

USART1->SR&=(~(1<<6)); //清除发送中断标记

IsSending=0;

}

}

}

main函数

int main(void)

{

Stm32_Clock_Init(9);

uart_init(72,115200);

delay_init(72);

while(1)//回显"每次"接收到的前10个字节

{

if((1==USART_RX_STA)&&(CountReciByte<=10))

{

SEND_BUF[SerialBufOffset] = REC;

USART_RX_STA=0;

SerialBufOffset++;

if(10==SerialBufOffset)

{

ReadZiku(100,100,SEND_BUF,Black, White);

//strcpy(SEND_BUF, "ABCDEFGHIJKLDR");

USART_SendXByte(USART1, SEND_BUF, 10);

//memset(SEND_BUF,0,sizeof(SEND_BUF));

SerialBufOffset=0;

CountReciByte=0;

//delay_ms(1000);

}

USART_RX_STA=0;//为了不让下一次接受上一次未取出的那个字节

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: