|
//-------------------------- AHR_USART.C -------------------------------------------------------------- #include "AHR_USART.H" u8 COMBUF[256]="0"; //接收缓冲,最大256个字节 u8 iComBuf=0; u8 ComNow =2; // 为区分5个串口共用一个缓冲区的识别问题而作的标记,显示时用颜色区分 //===================================================================================================== // 直接寄存器操作实现全部串口通信初始化及数据收发:如:US123ART45Init(3,9600,0x0C,2,0,0,0,0);串3优先级2 // TX-串口输出: 1-A9 ;2-A2;3-B10;4-C10;5-C12 //char str[]="4Step:1.RCC;2.AFIO;3.USART;4.NVIC"; // RX-串口输入: 1-A10;2-A3;3-B11;4-C11;5-D2 未完成:NVIC 仍然使用库函数 -- 20180728 -- //----------------------------------------------------------------------------------------------------- const u32 irqNOADcom[5]={37/*0xD4:COM1*/,38/*0xD8:COM2*/,39/*0xDC:3*/,52/*0x110:4*/,53/*0x114:5*/}; const u32 APB2IO_APB1US23ART45[10]={0x4004,0,0x04,0x20000,0x08,0x40000,0x10,0x80000,0x30,0x100000}; const u32 USART_REGADDR[5]={0x40013800,0x40004400,0x40004800,0x40004C00,0x40005000}; const u32 COMxBaudRate[4]={0xEA6/*9600*/,0x271/*57600*/,0x138/*115200*/,0x08C/*256000*/}; const u32 TXRX_PortSet[5][6]={{0x40010804,0x000000B0,0xFFFFFFBF,0x40010804,0x00000400,0xFFFFF4FF}, {0x40010800,0x00000B00,0xFFFFFBFF,0x40010800,0x00004000,0xFFFF4FFF}, {0x40010C04,0x00000B00,0xFFFFFBFF,0x40010C04,0x00004000,0xFFFF4FFF}, {0x40011004,0x00000B00,0xFFFFFBFF,0x40011004,0x00004000,0xFFFF4FFF}, {0x40011004,0x000B0000,0xFFFBFFFF,0x40011400,0x00000400,0xFFFFF4FF}}; void US123ART45Init(u8 iCOM,u32 baudRate,u8 Tx8Rx4,u8 priPS,u8 Ds1908,u8 St0115,u8 y1n0CRC,u8 HFr1c2) { NVIC_InitTypeDef structNVIC; //irqNOADcom[0]=USART1_IRQn; priPS-主副优先级级别(暂定相同) uint32_t tmpReg=0; //参数Ds1908=1:数据9位,=0:8位;St011522315=0,1,2,3;停止位=1,0.5, 2, 1.5 *(volatile unsigned long *)(0x40021018)|=APB2IO_APB1US23ART45[iCOM*2-2]; //打开 GPIOX 时钟 *(volatile unsigned long *)(0x4002101C)|=APB2IO_APB1US23ART45[iCOM*2-1]; //打开U(S)ARTX时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //所有涉及中断必须开放此时钟(外中断皆复用端口) *(volatile unsigned long *)TXRX_PortSet[iCOM-1][0]|=TXRX_PortSet[iCOM-1][1]; // TX *(volatile unsigned long *)TXRX_PortSet[iCOM-1][0]&=TXRX_PortSet[iCOM-1][2]; *(volatile unsigned long *)TXRX_PortSet[iCOM-1][3]|=TXRX_PortSet[iCOM-1][4]; // RX *(volatile unsigned long *)TXRX_PortSet[iCOM-1][3]&=TXRX_PortSet[iCOM-1][5]; tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x10); // 设置 USART_CR2 //--.LINEN.STOP[1:0],CLKEN.CPOL.CPHA.LBCL,--.LBDIE.LBDL.--,ADD[3:0] tmpReg&=(uint16_t)0xCFFF; // 1 1 0 0 , 1 1 1 1 ,1 1 .... 1 //清STOP if (St0115 != 0) tmpReg |= (St0115 << 12); // 停止位设置0-1;1-.5;2-2 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x10) = tmpReg; // 将设置写回寄存器CR2 tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C); // 设置 USART_CR1 // UE M,WAKE PCE PS PEIE,TXEIE TCIE RXNEIE IDLEIE,TE RE RWU SBK tmpReg&=0xE9F3; // 1 0, 1 0 0 1 , 1 1 1 1 , 0 0 1 1 // 清M等位 if (Ds1908 != 0) tmpReg |=0x00001000; //数据位9位; 缺省 Ds1908=0数据位8位 if (y1n0CRC!= 0) tmpReg |=0x00000400; //偶校验 ; 缺省y1n0CRC=0不校验 if (Tx8Rx4 != 0) tmpReg |=Tx8Rx4; //8-使能Tx模式;4-使能Rx模式;0xC-TxRx全能 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C) = tmpReg; // 将设置写回寄存器CR1 tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x14); // 设置 USART_CR3 // CTSIE CTSE RTSE,DMAT DMAR SCEN NACK,HDSEL IRLP IREN EIE tmpReg&=0xFCFF; // 1 0 0 , 1 1 1 1 , 1 1 1 1 //清CTSE/RTSE if (HFr1c2 != 0) tmpReg |= (HFr1c2 << 8); //HFr1c2 =0-禁止;1-RTS/2-CTS/3-R&CTS硬件流控制使能 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x14) = tmpReg; // 将设置写回寄存器CR3 switch (baudRate){ //tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x08); case 57600: tmpReg = COMxBaudRate[1]; break; // ^--与下面sprintf()语句结合直接读波特率16进制 case 115200: tmpReg = COMxBaudRate[2]; break; // 如果计算则用到下面两句: case 256000: tmpReg = COMxBaudRate[3]; break; //tmpReg = (u32)Mantissa <<4; //高12位-整数部分 case 9600: //tmpReg |= (0x0000000F & Fraction); // 低 4位-小数部分 default: tmpReg = COMxBaudRate[0]; break; // v--形成数组再经switch查询,写回波特率寄存器 } //sprintf(str,"baudRate:%8X",tmpReg); LCD_ShowString(10,160,240,180,16,(u8*)str); *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x08) = tmpReg; // 将波特率写入寄存器 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C) |=0x00002000; //使能串口 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x00) &=0xFFFFFFBF; //清除中断标志 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C) |=0x00000020; //使能串口接收缓冲非空中断 structNVIC.NVIC_IRQChannel = irqNOADcom[iCOM-1]; // 串口中断通道 structNVIC.NVIC_IRQChannelPreemptionPriority = priPS; // 不能相同 //抢占优先级 structNVIC.NVIC_IRQChannelSubPriority = priPS; // 不能相同 //子优先级 structNVIC.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&structNVIC); //根据指定参数初始化VIC寄存器 } void USART2_IRQHandler(void) { //串口2中断服务程序, switch语句专用于格式化以回车换行结束的ASCii串 u8 r=0; static u8 i=0; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { //接收中断 if(ComNow!=2) ComNow=2; r=USART_ReceiveData(USART2); //读串2到全局数组 switch (r){ case 0x0A: iComBuf=i; i=0; break; case 0x0D: USART_ClearITPendingBit(USART2,USART_IT_RXNE); break; default: COMBUF[i]=r; i++; i&=0xFF; break; // 限制在0~255之间 } } if (USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET) //溢出则必须清零 { USART_ClearFlag(USART2, USART_FLAG_ORE); USART_ReceiveData(USART2); } } void UART5_IRQHandler(void) { // 串口5中断服务程序 if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(UART5,USART_IT_RXNE); //清除接收中断标志 if(ComNow!=5) ComNow=5; COMBUF[iComBuf]=USART_ReceiveData(UART5); iComBuf++; iComBuf&=0xFF; // 限制在0~255之间 } USART_ClearFlag(UART5,USART_FLAG_TC); } void UART4_IRQHandler(void) { // 串口4中断服务程序 if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(UART4,USART_IT_RXNE); if(ComNow!=4) ComNow=4; COMBUF[iComBuf]=USART_ReceiveData(UART4); //读串2到全局数组 iComBuf++; iComBuf&=0xFF; // 限制在0~255之间 } USART_ClearFlag(UART4,USART_FLAG_TC); } void USART3_IRQHandler(void) { // 串口3中断服务程序 if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART3,USART_IT_RXNE); if(ComNow!=3) ComNow=3; COMBUF[iComBuf]=USART_ReceiveData(USART3); //读串3到全局数组 iComBuf++; iComBuf&=0xFF; } USART_ClearFlag(USART3,USART_FLAG_TC); } void USART1_IRQHandler(void) { // 串口1中断服务程序,收到后随即发出去(为普中开发板而暂时保留) if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ //接收中断 COMBUF[255] = USART_ReceiveData(USART1); USART_SendData(USART1, COMBUF[255]); while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); } USART_ClearFlag(USART1,USART_FLAG_TC); } struct __FILE { int handle; }; FILE __stdout; // 标准库需要的支持函数 _sys_exit(int x) { x = x; } // 定义_sys_exit()以避免使用半主机模式 int fputc(int ch,FILE *p) { // 默认函数在使用 printf函数时自动调用 USART_SendData(USART1,(u8)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);return ch; } //-------------------------------------------- end of AHR_USART.C ------------------------------------- //---------------- AHR_USART.H ------------------------------------------------------------------------ #ifndef __usart_H #define __usart_H #include "aiherong.h" extern u8 iComBuf; // 接收缓冲区指针 extern u8 COMBUF[256]; // 接收缓冲区,最大256个字节 extern u8 ComNow; // 5个COM共用公共接收缓冲区COMBUF,以此区分串口号 void US123ART45Init(u8 iCOM,u32 baudRate,u8 Tx8Rx4,u8 priPS,u8 Ds1908,u8 St0115,u8 y1n0CRC,u8 HFr1c2); #endif //-------------------------------------------- end of AHR_USART.H ------------------------------------ |
微信公众号
手机版
//===================== AiHeRong.H ========================== 2018-0712 ===============================
#include "stm32f10x.h"
#define SYSCLK 72
#define REALADDR(addrNum) *((volatile unsigned long *)(addrNum))
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //bit-baud is CMSIS 功能 20180426
//凡艾和荣编写的工程均包含该文件,包括最典型的宏定义和最广泛的移植要点! 【目标】:所有移植全在此进行!!
#include "AHR_TouchFilm.h"
#include "AHR_SysTick.h"
#include "AHR_Lcdtft.h"
#include "AHR_24Cxx.h"
#include "AHR_usart.h"
#include "spi.h"
// 各模块的依存关系要说明,独立性依次为:->SysTick->LcdTFT,24Cxx->TouchFilm-> ....
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <cpu.h>
#include <lib_def.h>
#include <lib_ascii.h>
#include <lib_math.h>
#include <lib_mem.h>
#include <lib_str.h>
#include <bsp.h>
#include <os.h>
int SystemDeviceInit(void); // 为uCOSiii的主函数规范而集中初始化设备 全成功才返回TRUE; 20180922
// 以下暂时保留: 2018-08-09
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+ 8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+ 8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+ 8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+ 8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+ 8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+ 8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+ 8) //0x40011E08
//IO口操作,只对单一的IO口! //确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
//------------------------------------------------------ end of AiHeRong.H ----------------------------
while (USART_GetITStatus(USART2,USART_IT_RXNE)==RESET) //在接收中断之外读全局数组COMBUF
if((REALADDR(USART2_BASE)&0x20)==0) 或 if(USART_GetITStatus(USART2,USART_IT_RXNE)==RESET)
for (i=iComBuf;i<N_BUF;i++) {
LCD_ShowChar(i*8,60,(char)COMBUF[i],16,0);
}