新手上路
- 积分
- 23
- 金钱
- 23
- 注册时间
- 2020-3-31
- 在线时间
- 9 小时
|
6金钱
(1)#include "usart.h"
#include "sys.h"
usart.c 文件
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h" //ucos 使用
#endif
////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32开发板
//串口1初始化
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/8/18
//版本:V1.5
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//********************************************************************************
//V1.3修改说明
//支持适应不同频率下的串口波特率设置.
//加入了对printf的支持
//增加了串口接收命令功能.
//修正了printf第一个字符丢失的bug
//V1.4修改说明
//1,修改串口初始化IO的bug
//2,修改了USART_RX_STA,使得串口最大接收字节数为2的14次方
//3,增加了USART_REC_LEN,用于定义串口最大允许接收的字节数(不大于2的14次方)
//4,修改了EN_USART1_RX的使能方式
//V1.5修改说明
//1,增加了对UCOSII的支持
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
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
//end
#if EN_USART1_RX
static void TIM5_init(u16 ms);
#endif
//////////////////////////////////////////////////////////////////
#if EN_USART1_RX //如果使能了接收 做了修改
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
void USART1_IRQHandler(void)//串口一中断
{
u8 res;
if(USART1->SR&(1<<5))//接收到数据
{
res=USART1->DR;
TIM5->CNT = 0;
if((USART_RX_STA&0x8000) == 0)
{
TIM5->CR1 |= 0x01;
USART_RX_BUF[USART_RX_STA&0x3FFF] = res;
USART_RX_STA++;
if(USART_RX_STA > (UART3_RX_BUF_MAX -1))
{
USART_RX_STA = 0;
}
}
}
}
static void TIM5_init(u16 ms)
{
RCC->APB1ENR |= 1<<3; //使能TIM5时钟
TIM5->ARR = ms*10 - 1; //ms*10次计数后溢出(7200分频刚好ms毫秒后溢出一次)
TIM5-> SC = 7200-1; //7200分频
TIM5->DIER |= 1<<0; //使能TIM5更新中断
TIM5->CR1 |= 0x01; //启动TIM5
MY_NVIC_Init(2,3,TIM5_IRQn,2); //次高抢占优先级,最低响应优先级
}
void TIM5_IRQHandler(void)
{
if(TIM5->SR & 0x0001) //计时溢出
{
USART_RX_STA |= 0x8000;
USART_RX_BUF[USART_RX_STA&0x3FFF] = '\0';
TIM5->CR1 &= ~(0x01); //disable TIM5
}
TIM5->SR &= ~(1<<0); //清除中断标志位
}
#endif
//初始化IO 串口1
//pclk2 CLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
GPIOA->CRH&=0XFFFFF00F;//IO状态设置
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
#if EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
TIM5_init(10);
MY_NVIC_Init(2,1,USART1_IRQn,2);//组2
#endif
}
//UART1 send len byte data from buffer buf
static void uart1SendData(const u8* buf, u16 len)
{
while(len)
{
while((USART1->SR&0x40) == 0)
;
USART1->DR = *buf;
buf++;
len--;
}
}
//-----------------------------------------------------------
#if EN_UART3_RX
static void TIM4_init(u16 ms);
#endif
//初始化IO 串口3
//pclk1 CLK1时钟频率(Mhz)
//bound:波特率
void uart3_init(u32 pclk1,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<3; //使能PORTB口时钟
RCC->APB1ENR|=1<<18; //使能串口时钟
GPIOB->CRH&=0XFFFF00FF;//IO状态设置
GPIOB->CRH|=0X00008B00;//IO状态设置
RCC->APB1RSTR|=1<<18; //复位串口3
RCC->APB1RSTR&=~(1<<18);//停止复位
//波特率设置
USART3->BRR=mantissa; // 波特率设置
USART3->CR1|=0X200C; //1位停止,无校验位.
#if EN_UART3_RX //如果使能了接收
//使能接收中断
USART3->CR1|=1<<8; //PE中断使能
USART3->CR1|=1<<5; //接收缓冲区非空中断使能
TIM4_init(10);
MY_NVIC_Init(1,1,USART3_IRQn,2);//最高抢占优先级,最高响应优先级
clearUart3Status();
#endif
}
//UART3 send len byte data from buffer buf
static void uart3SendData(const u8* buf, u16 len)
{
while(len)
{
while((USART3->SR&0x40) == 0)
;
USART3->DR = *buf;
buf++;
len--;
}
}
//串口3发送字符串
void uart3SendStr(const char *str)
{
char* s = (char*)str;
while(*s)
{
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕
USART3->DR = *s;
s++;
}
}
#if EN_UART3_RX
u8 UART3_RX_BUF[UART3_RX_BUF_MAX];
u16 UART3_RX_STA = 0;
void USART3_IRQHandler(void)
{
u8 dat;
if(USART3->SR & (1<<5))
{
dat = USART3->DR;
TIM4->CNT = 0;
if((UART3_RX_STA&0x8000) == 0)
{
TIM4->CR1 |= 0x01;
UART3_RX_BUF[UART3_RX_STA&0x3FFF] = dat;
UART3_RX_STA++;
if(UART3_RX_STA > (UART3_RX_BUF_MAX-1))
{
UART3_RX_STA = 0;
}
}
}
}
static void TIM4_init(u16 ms)
{
RCC->APB1ENR |= 1<<2; //使能TIM4时钟
TIM4->ARR = ms*10 - 1; //ms*10次计数后溢出(7200分频刚好ms毫秒后溢出一次)
TIM4-> SC = 7200-1; //7200分频
TIM4->DIER |= 1<<0; //使能TIM4更新中断
TIM4->CR1 |= 0x01; //启动TIM4
MY_NVIC_Init(2,3,TIM4_IRQn,2); //次高抢占优先级,最低响应优先级
}
void TIM4_IRQHandler(void)
{
if(TIM4->SR & 0x0001) //计时溢出
{
UART3_RX_STA |= 0x8000;
UART3_RX_BUF[UART3_RX_STA&0x3FFF] = '\0';
TIM4->CR1 &= ~(0x01); //disable TIM4
}
TIM4->SR &= ~(1<<0); //清除中断标志位
}
#endif
//--------------------------------------------------------
#if EN_UART4_RX //如果使能了接收
//串口4中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 UART4_RX_BUF[USART_REC_LEN ]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 UART4_RX_STA=0; //接收状态标记
void UART4_IRQHandler(void)
{
u8 res;
if(UART4->SR&(1<<5))//接收到数据
{
res=UART4->DR;
if((UART4_RX_STA&0x8000)==0)//接收未完成
{
if(UART4_RX_STA&0x4000)//接收到了0x0d
{
if(res!=0x0a)UART4_RX_STA=0;//接收错误,重新开始0a:"\r"
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>(UART3_RX_BUF_MAX -1))
UART4_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
//--------------------------------------------------------
//初始化IO 串口4
//pclk1 CLK1时钟频率(Mhz)
//bound:波特率
void uart4_init(u32 pclk1,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<4; //使能PORTC口时钟
RCC->APB1ENR|=1<<19; //使能串口时钟
GPIOC->CRH&=0XFFFF00FF;//IO状态设置
GPIOC->CRH|=0X00008B00;//IO状态设置
RCC->APB1RSTR|=1<<19; //复位串口4
RCC->APB1RSTR&=~(1<<19);//停止复位
//波特率设置
UART4->BRR=mantissa; // 波特率设置
UART4->CR1|=0X200C; //1位停止,无校验位.
#if EN_UART4_RX //如果使能了接收
//使能接收中断
UART4->CR1|=1<<8; //PE中断使能
UART4->CR1|=1<<5; //接收缓冲区非空中断使能
//TIM4_init(10);
MY_NVIC_Init(1,1,UART4_IRQn,2);//最高抢占优先级,最高响应优先级
clearUart4Status();
#endif
}
//UART3 send len byte data from buffer buf
static void uart4SendData(const u8* buf, u16 len)
{
while(len)
{
while((UART4->SR&0x40) == 0)
;
UART4->DR = *buf;
buf++;
len--;
}
}
//--------------------------------------------------------
//串口X发送len个字节
//@param uartX: 使用哪个串口发送
//@param buf: 待发送的缓冲区的指针
//@param len: 发送长度
void uartXSendData(u8 uartX, const u8* buf, u16 len)
{
switch(uartX)
{
case 1:
uart1SendData(buf, len);
break;
case 3:
uart3SendData(buf, len);
break;
case 4:
uart4SendData(buf, len);
break;
default:
break;
}
}
void myPrintf(u8 uartX, const char* fmt, ...)
{
#define TEMP_BUF_MAX 200
char temp[TEMP_BUF_MAX];
char *buf = NULL;
u16 cnt = 0;
va_list ap; //可变参数列表,即三个句点...
buf = temp;
__va_start(ap, fmt); //__va_start(可变参数列表...,可变参数列表...的前一个参数)
cnt = vsprintf(buf, fmt, ap); //格式化后的字符串长度,包括\0 = vsprintf(格式化后字符串的存放缓冲区指针,待格式的字符串的指针,可变参数列表...)
__va_end(ap); //与__va_start()配对使用,释放可变参数列表
uartXSendData(uartX, (const u8*)buf, cnt);
}
(2)usart.h 文件
#ifndef __USART_H
#define __USART_H
#include "sys.h"
#include "stdio.h"
#include "stdarg.h"
////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32开发板
//串口1初始化
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/8/18
//版本:V1.5
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//********************************************************************************
//V1.3修改说明
//支持适应不同频率下的串口波特率设置.
//加入了对printf的支持
//增加了串口接收命令功能.
//修正了printf第一个字符丢失的bug
//V1.4修改说明
//1,修改串口初始化IO的bug
//2,修改了USART_RX_STA,使得串口最大接收字节数为2的14次方
//3,增加了USART_REC_LEN,用于定义串口最大允许接收的字节数(不大于2的14次方)
//4,修改了EN_USART1_RX的使能方式
//V1.5修改说明
//1,增加了对UCOSII的支持
////////////////////////////////////////////////////////////////////////////////
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
#define EN_UART3_RX 1 //true: enable UART3 receive; false: disable UART3 receive
#define EN_UART4_RX 1
#define UART3_RX_BUF_MAX 1024 //max length of UART3 receive buffer
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
extern u8 UART3_RX_BUF[UART3_RX_BUF_MAX];
extern u16 UART3_RX_STA;
extern u8 UART4_RX_BUF[USART_REC_LEN ]; //接收缓冲,最大USART_REC_LEN个字节.
extern u16 UART4_RX_STA; //接收状态标记
void uart_init(u32 pclk2,u32 bound);
void uart3_init(u32 pclk1,u32 bound);
void uart4_init(u32 pclk1,u32 bound);
void uart3SendStr(const char *str);
#define didUart3DataCome() (UART3_RX_STA & 0x8000)
#define clearUart3Status() (UART3_RX_STA=0)
#define getUart3DataLen() (UART3_RX_STA & 0x3FFF)
#define clearUart4Status() (UART4_RX_STA=0)
void myPrintf(u8 uartX, const char* fmt, ...);
#endif
(3)main.c 文件
include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
int main(void)
{
u8 len,t;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时函数初始化
uart_init(72,115200); //串口1初始化
uart4_init(36,115200); //串口4初始化
myPrintf(1,"AT+RST\r\n");//给WIFI模块复位一下
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
myPrintf(1,"AT+CIPMUX=0\r\n");//设置为单连接模式
delay_ms(1000);
myPrintf(1,"AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n");//连接onenet HTTP服务器183.230.40.33/80
delay_ms(1000);
myPrintf(1, "AT+CIPMODE=1\r\n");//开启透传模式
delay_ms(1000);
myPrintf(1,"AT+CIPSEND\r\n");//数据开始透传
delay_ms(1000);
delay_ms(500);
myPrintf(4,"AT+RST\r\n");//给WIFI模块复位一下
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
myPrintf(4,"AT+CIPMUX=1\r\n");//开启多连接模式
delay_ms(1000);LED=1;//LED灭
myPrintf(4,"AT+CIPSERVER=1,8089\r\n");//开启服务器模式
delay_ms(1000);
while(1)
//串口4发送和接收数据
{
if(UART4_RX_STA&0x8000)
{
myPrintf(1,(const char*)UART4_RX_BUF);
myPrintf(1,"\r\n");
UART4_RX_STA=0;
}
}
}
|
|