|
#include "sys.h"
#include "usart.h"
#include "stdarg.h"
#include "main.h"
//////////////////////////////////////////////////////////////////////////////////
//如果使用ucos,則包括下面的頭文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
//////////////////////////////////////////////////////////////////////////////////
/*
五個串口使用
USART1 TX ---->PA9
RX----->PA10
USART2 TX ---->PA2
RX----->PA3
USART3 TX ---->PB10
RX----->PB11
UART4 TX ---->PC10
RX----->PC11
UART5 TX ---->PC12
RX----->PD2
*/
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//加入以下代碼,支持printf函數,而不需要選擇use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//標準庫需要的支持函數
struct __FILE
{
int handle;
};
FILE __stdout;
//定義_sys_exit()以避免使用半主機模式
void _sys_exit(int x)
{
x = x;
}
//重定義fputc函數 //串口1使用printf函數
int fputc(int ch, FILE *f)
{
while((USART2->SR&0X40)==0);//循環發送,直到發送完畢
USART2->DR = (u8) ch;
return ch;
}
//int fgetc2(FILE *stream)//獲取字符
//{
//
//}
#endif
/*使用microLib的方法*/
/*
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}
return ch;
}
int GetKey (void) {
while (!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0x1FF));
}
*/
#if EN_USART1_RX //如果使能了接收
//串口1中斷服務程序
//注意,讀取USARTx->SR能避免莫名其妙的錯誤
u8 USART1_RX_BUF[USART1_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節.
u8 USART2_RX_BUF[USART2_REC_LEN];
u8 USART3_RX_BUF[USART3_REC_LEN];
u8 UART4_RX_BUF[UART4_REC_LEN];
u8 UART5_RX_BUF[UART5_REC_LEN];
//接收狀態
//bit15, 接收完成標志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字節數目
u16 USART1_RX_STA=0; //接收狀態標記
u16 USART2_RX_STA=0;
u16 USART3_RX_STA=0;
u16 UART4_RX_STA=0;
u16 UART5_RX_STA=0;
u8 Res;
void usart1_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時鐘
//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
//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寄存器
//USART 初始化設置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
USART_Cmd(USART1, ENABLE); //使能串口1
}
void USART1_IRQHandler(void) //串口1中斷服務程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
{
Res =USART_ReceiveData(USART1); //讀取接收到的數據
if((USART1_RX_STA&0x8000)==0)//接收未完成
{
if(USART1_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART1_RX_STA=0;//接收錯誤,重新開始
else
{
USART1_RX_STA|=0x8000;
} //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)USART1_RX_STA|=0x4000;
else
{
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ;
USART1_RX_STA++;
if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收數據錯誤,重新開始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntExit();
#endif
}
#endif
void usart2_init(u32 bound)
{
//GPIO端口設置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART2,GPIOB時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//USART2_TX GPIOA2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
//USART2_RX GPIOA3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//搶占優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器
//USART 初始化設置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
USART_Cmd(USART2, ENABLE); //使能串口2
}
void USART2_IRQHandler(void) //串口2中斷服務程序
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
{
Res =USART_ReceiveData(USART2); //讀取接收到的數據
receive();
}
}
void usart3_init(u32 bound)
{
//GPIO端口設置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能USART3,GPIOB時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
//USART3_TX GPIOB10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.10
//USART3_RX GPIOB11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11
//Usart3 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//搶占優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器
//USART 初始化設置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
USART_Init(USART3, &USART_InitStructure); //初始化串口3
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
USART_Cmd(USART3, ENABLE); //使能串口3
}
void USART3_IRQHandler(void) //串口3中斷服務程序
{
u8 Res;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
{
Res =USART_ReceiveData(USART3); //讀取接收到的數據
if((USART3_RX_STA&0x8000)==0)//接收未完成
{
if(USART3_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART3_RX_STA=0;//接收錯誤,重新開始
else
{
USART3_RX_STA|=0x8000;
} //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)USART3_RX_STA|=0x4000;
else
{
USART3_RX_BUF[USART3_RX_STA&0X3FFF]=Res ;
USART3_RX_STA++;
if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收數據錯誤,重新開始接收
}
}
}
}
}
//void uart4_init(u32 bound)
//{
// //GPIO端口設置
// GPIO_InitTypeDef GPIO_InitStructure;
// USART_InitTypeDef USART_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
//
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能UART4,GPIOC時鐘
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
//
//
// //USART4_TX GPIOC10
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
// GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC10
//
// //USART4_RX GPIOC11
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
// GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.11
// //Usart4 NVIC 配置
// NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//搶占優先級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_8b;//字長為8位數據格式
// USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
// USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
// USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
// USART_Init(UART4, &USART_InitStructure); //初始化串口3
// USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
// USART_Cmd(UART4, ENABLE); //使能串口3
//}
void UART4_IRQHandler(void) //串口4中斷服務程序
{
u8 Res;
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
{
Res =USART_ReceiveData(UART4); //讀取接收到的數據
if((UART4_RX_STA&0x8000)==0)//接收未完成
{
if(UART4_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)UART4_RX_STA=0;//接收錯誤,重新開始
else
{
UART4_RX_STA|=0x8000;
} //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)UART4_RX_STA|=0x4000;
else
{
UART4_RX_BUF[UART4_RX_STA&0X3FFF]=Res ;
UART4_RX_STA++;
if(UART4_RX_STA>(UART4_REC_LEN-1))UART4_RX_STA=0;//接收數據錯誤,重新開始接收
}
}
}
}
}
//void uart5_init(u32 bound)
//{
// //GPIO端口設置
// GPIO_InitTypeDef GPIO_InitStructure;
// USART_InitTypeDef USART_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
//
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能UART5,GPIOC時鐘
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
//
//
// //USART5_TX GPIOC12
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
// GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC10
//
// //USART5_RX GPIOD2
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
// GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOC.11
// //Usart5 NVIC 配置
// NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//搶占優先級3
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子優先級3
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
// NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器
//
// //USART 初始化設置
// USART_InitStructure.USART_BaudRate = bound;//串口波特率
// USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
// USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
// USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
// USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
// USART_Init(UART5, &USART_InitStructure); //初始化串口3
// USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
// USART_Cmd(UART5, ENABLE); //使能串口3
//}
void UART5_IRQHandler(void) //串口4中斷服務程序
{
u8 Res;
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
{
Res =USART_ReceiveData(UART5); //讀取接收到的數據
if((UART5_RX_STA&0x8000)==0)//接收未完成
{
if(UART5_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)UART5_RX_STA=0;//接收錯誤,重新開始
else
{
UART5_RX_STA|=0x8000;
} //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)UART5_RX_STA|=0x4000;
else
{
UART5_RX_BUF[UART5_RX_STA&0X3FFF]=Res ;
UART5_RX_STA++;
if(UART5_RX_STA>(UART5_REC_LEN-1))UART5_RX_STA=0;//接收數據錯誤,重新開始接收
}
}
}
}
}
//串口格式化打印函數
void UsartPrintf(USART_TypeDef *USARTx, char *fmt,...)
{
unsigned char UsartPrintfBuf[296];
va_list ap;
unsigned char *pStr = UsartPrintfBuf;
va_start(ap, fmt);
vsprintf((char *)UsartPrintfBuf, fmt, ap); //格式化
va_end(ap);
while(*pStr != 0)
{
USART_SendData(USARTx, *pStr++);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
}
}
|
-
51hei.png
(6.46 KB, 下載次數: 59)
下載附件
2023-4-7 15:31 上傳
-
-
USART.rar
2023-4-5 23:18 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
4.36 KB, 下載次數: 16, 下載積分: 黑幣 -5
上圖4個文件
評分
-
查看全部評分
|