bsp_DMAusart1.h
#ifndef __BSP_DMAUSART1_H#define __BSP_DMAUSART1_H//-------------------------------------------------------------------#include "stm32f10x.h"#include <string.h>//-------------------------------------------------------------------#define USART1_REC_LEN 58 //定义最大接收字节数 58typedef struct{ uint8_t Tx_buf[USART1_REC_LEN]; //发送缓冲区 uint8_t Tx_len; //发送长度 uint8_t Rx_buf[USART1_REC_LEN]; //接收缓冲区 uint8_t Rx_len; //接收长度 uint8_t Rx_end_flag; //接收完成标志 uint8_t Rx_time_start; //计时启动标志 uint16_t Rx_time; //1祯数据接收时长(mSec) }USART1_DEF;extern USART1_DEF OneUART;//-------------------------------------------------------------------void USART1_Init(uint32_t BAND,uint8_t *SendAddres,uint8_t *RecAddres,uint8_t len);void DMA_USART1RxTx_Init(uint8_t *SendAd,uint8_t *RecAddres,uint8_t len);void NVIC_USART1_Configuration(void);void USART1_SendChar(u8 t);void USART_printf(USART_TypeDef* USARTx, uint8_t *Data,...);void USART1_SendString(void* buffer, uint16_t size);void USART1_Encryption_SendString(void* buffer, uint16_t size);uint16_t USART1_DMASendString(void* buffer, uint16_t size);uint16_t USART1_Encryption_DMASendString(void* buffer, uint16_t size);#endif /* __USART1_H */
bsp_DMAusart1.c
#include "bsp_DMAusart1.h"USART1_DEF OneUART;/*** @brief USART1初始化* @param BAND,波特率(2400,4800,9600,38400,115200)* Send_pf,发送数据缓冲区* Rec_pf,接收数据缓冲区* buf_len,接收数据缓冲区长度* @retval 无*/void USART1_Init(uint32_t BAND,uint8_t *Send_pf,uint8_t *Rec_pf,uint8_t buf_len){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* config USART1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOB, ENABLE); /* USART1 GPIO config */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能端口重映射 /* Configure USART1 Tx (PB6) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure USART1 Rx (PB7) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); /* RS485,Tx/Rx Control PB5 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_5); GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE); /* USART1 mode config */ USART_InitStructure.USART_BaudRate = BAND; USART_InitStructure.USART_WordLength = USART_WordLength_8b; 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); USART_Cmd(USART1, ENABLE); USART_ClearFlag(USART1, USART_FLAG_TC); //清发送完成标志 USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启空闲中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断 USART_ITConfig(USART1, USART_IT_TC, ENABLE); //开启发送完成中断 NVIC_USART1_Configuration(); DMA_USART1RxTx_Init(Send_pf,Rec_pf,buf_len);//DMA初始化}/*** @brief 配置USART1中断* @param * @retval 无*/static void NVIC_USART1_Configuration(void){ NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the USARTy Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //开启接收完成中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the USARTy Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;//开启发送完成中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);}/*** @brief DMA_USART1初始化* @param Send_pf,发送数据缓冲区* Rec_pf,接收数据缓冲区* buf_len,接收数据缓冲区长度* @retval 无*/static void DMA_USART1RxTx_Init(uint8_t *Send_pf,uint8_t *Rec_pf,uint8_t buf_len){ DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_Cmd(DMA1_Channel5,DISABLE); //关闭DMA DMA_DeInit(DMA1_Channel5); //恢复默认 DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&USART1->DR; //设置串口发送数据寄存器 DMA_InitStructure.DMA_MemoryBaseAddr=(u32)Rec_pf; //设置发送缓冲区首地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //设置外设位目标,内存缓冲区 <- 外设寄存器 DMA_InitStructure.DMA_BufferSize=buf_len; //需要发送的字节数,这里其实可以设置为0,因为在实际要发送的时候,会重新设置次值 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节宽度 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存字节宽度 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //正常模式 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //高优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //关闭内存到内存的DMA模式 DMA_Init(DMA1_Channel5,&DMA_InitStructure); //配置DMA1的6通道 DMA_Cmd(DMA1_Channel5,ENABLE); //使能DMA DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr= (u32)&USART1->DR; //初始化外设地址 DMA_InitStructure.DMA_MemoryBaseAddr=(u32)Send_pf; //内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据来源 DMA_InitStructure.DMA_BufferSize=0; //发送长度为0 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节宽度 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存字节宽度 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //正常模式 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //高优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //关闭内存到内存的DMA模式 DMA_Init(DMA1_Channel4,&DMA_InitStructure); //配置DMA1的7通道 DMA_Cmd(DMA1_Channel4,ENABLE); //使能DMA USART_ITConfig(USART1, USART_DMAReq_Tx, ENABLE); //开启中断USART_DMAReq_Tx USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //开启接收接收 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //开启接收发送// DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); //配置DMA发送完成后产生中断} /** * @brief USART1_DMA发送完成中断 * @param 无 * @retval 无 */void DMA1_Channel4_IRQHandler(void){ if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET) {//发送完成中断 DMA_ClearFlag(DMA1_FLAG_TC4); //GPIO_ResetBits(GPIOB,GPIO_Pin_5); }} /** * @brief USART1串口接收中断 * @param 无 * @retval 无 */void USART1_IRQHandler(void) //串口1中断服务程序{ static uint8_t LEN=0; uint8_t Clear=Clear,tmp; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {//接收中断 OneUART.Rx_buf[LEN++]= USART1->DR; //读取接收到的数据 LEN= (LEN < USART1_REC_LEN)?LEN:0; }else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) {//空闲中断,1桢数据接收完毕 Clear=USART1->SR; //读SR寄存器 Clear=USART1->DR; //读DR寄存器,(先读SR,再读DR就是清除IDLE标志中断) OneUART.Rx_end_flag = 1; //接收完成标志 DMA_Cmd(DMA1_Channel5,DISABLE); OneUART.Rx_len=USART1_REC_LEN-DMA_GetCurrDataCounter(DMA1_Channel5); DMA_SetCurrDataCounter(DMA1_Channel5,USART1_REC_LEN); //设置DMA缓冲区长度 DMA_Cmd(DMA1_Channel5,ENABLE); }else if(USART_GetITStatus(USART1, USART_IT_TC) != RESET) {//发送完成中断 USART_ClearITPendingBit(USART1, USART_IT_TC); //清除USART1发送完成中断标志 DMA_ClearFlag(DMA1_FLAG_TC4); //清零标志位 GPIO_ResetBits(GPIOB,GPIO_Pin_5); //发送完成,等待接收数据 }} /** * @brief DMA_USART1数据发送 * @param buffer,发送数据地址 * size,发送数据长度 * @retval size */uint16_t USART1_DMASendString(void* buffer, uint16_t size){ if(!size) return 0; //判断长度是否有效 while(DMA_GetCurrDataCounter(DMA1_Channel4)); //检查DMA通道内是否还有数据 if(buffer) //发送数据拷贝到发送缓存区 memcpy(OneUART.Tx_buf, buffer,(size > 1024?1024:size)); DMA_Cmd(DMA1_Channel4, DISABLE); //DMA发送数据要先关闭,设置发送数据长度 开启DMA DMA1_Channel4->CNDTR = size; //设置发送长度 GPIO_SetBits(GPIOB,GPIO_Pin_5); DMA_Cmd(DMA1_Channel4, ENABLE); //启动DMA发送 return size;} /** * @brief DMA_USART1加密数据发送 * @param buffer,发送数据地址 * size,发送数据长度 * @retval size */uint16_t USART1_Encryption_DMASendString(void* buffer, uint16_t size){ if(!size) return 0; //判断长度是否有效 while(DMA_GetCurrDataCounter(DMA1_Channel4)); //检查DMA通道内是否还有数据 if(buffer) //发送数据拷贝到发送缓存区 { //encryption(buffer,size);//使能加密 memcpy(OneUART.Tx_buf, buffer,(size > 1024?1024:size)); } DMA_Cmd(DMA1_Channel4, DISABLE); //DMA发送数据要先关闭,设置发送数据长度 开启DMA DMA1_Channel4->CNDTR = size; //设置发送长度 GPIO_SetBits(GPIOB,GPIO_Pin_5); DMA_Cmd(DMA1_Channel4, ENABLE); //启动DMA发送 return size;} /** * @brief USART1发送数据1个字节 * @param dat,发送数据 * @retval 无 */void USART1_SendChar(u8 t){ USART_SendData(USART1,t); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); while((USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET));//等待串口发送完毕} /** * @brief USART1发送字符串 * @param dat,发送数据 * @retval 无 */void USART1_SendString(void* buffer, uint16_t size){ uint8_t i=0,*buf; buf=buffer; GPIO_SetBits(GPIOB,GPIO_Pin_5); while(size--) { USART1_SendChar(buf[i++]); } GPIO_ResetBits(GPIOB,GPIO_Pin_5);} /** * @brief USART1加密发送字符串 * @param dat,发送数据 * @retval 无 */void USART1_Encryption_SendString(void* buffer, uint16_t size){ uint8_t i=0,*buf; //encryption(buffer,size); buf=buffer; GPIO_SetBits(GPIOB,GPIO_Pin_5); while(size--) { USART1_SendChar(buf[i++]); } GPIO_ResetBits(GPIOB,GPIO_Pin_5);}
bsp_tim3.h
#ifndef __BSP_TIM3_H#define __BSP_TIM3_H#include "stm32f10x.h"void TIM3_Int_Init(u16 arr,u16 psc);#endif // __BSP_TIM3_H
bsp_tim3.c
#include "bsp_tim3.h"extern uint16_t time;//void TIM3_Int_Init(u16 arr,u16 psc)//{// TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;// NVIC_InitTypeDef NVIC_InitStructure;// RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能// // TIM_TimeBaseStructure.TIM_Period = arr; // TIM_TimeBaseStructure.TIM_Prescaler =psc; // TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);// // TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); // NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // TIM_Cmd(TIM3, ENABLE); //}void TIM3_Int_Init(u16 arr,u16 psc){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 //定时器TIM3初始化 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断 TIM_ClearFlag(TIM3,TIM_IT_Update ); //中断优先级NVIC设置 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx }//定时器3中断服务程序void TIM3_IRQHandler(void) //TIM3中断{ static u16 mS_Cnt_0=0; static u16 mS_Cnt_1=0; static u16 mS_Cnt_2=0; static u16 mS_Cnt_3=0; static u16 mS_Cnt_4=0; if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否 // if(TIM2->SR&0X0001)//寄存器操作 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志 ,库函数操作 //---------------------------------------[2] time++; //---------------------------------------[5] }}// 延迟分钟函数uint8_t delayed(uint8_t minute){ // 1分钟的 if(time == 6000 * minute) { time = 0; return 0; }}//void TIM3_IRQHandler(void) //TIM3中断//{// static uint16_t Sys_Cnt[5]={0};// if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否// {// time++;// TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志 ,库函数操作 TIM_IT_Update// }//}//void BASIC_TIM_IRQHandler(void)//{// if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) // { // time++;// TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update); // } //}
main.c
/**********************芯片:STM32F103C8T6实现功能:引脚:PC13***********************/#include "stm32f10x.h"#include "bsp_DMAusart1.h"#include "bsp_tim3.h"uint16_t time=0;uint8_t time10 = 0;int main(){ USART1_Init(115200, OneUART.Tx_buf, OneUART.Rx_buf, USART1_REC_LEN); USART1_DMASendString("time end!",sizeof("time end!")); //每次进入中断服务程序间隔时间为((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+7199)/72M)*(1+9999)=1秒 //TIM3_Int_Init(9999, 71); // 1ms //TIM3_Int_Init(59999, 71); // 60ms //TIM3_Int_Init(59999, 7199); // 6s //TIM3_Int_Init(59999, 35999); // 30s while(1) { if(OneUART.Rx_end_flag) { if(OneUART.Rx_buf[0]== 0x01) { OneUART.Rx_buf[0] = 0x00; TIM3_Int_Init(59999, 35999); // 30s } if(OneUART.Rx_buf[0]== 0x02) { OneUART.Rx_buf[0] = 0x00; TIM_Cmd(TIM3, DISABLE); } } // 1分钟 if(time == 2) { time = 0; // USART1_DMASendString("time end!",sizeof("time end!")); USART1_DMASendString("1分钟!",sizeof("1分钟!")); time10++; } // 10分钟 if(time10 == 10) { time10 = 0; USART1_DMASendString("10分钟!", sizeof("10分钟!")); } }}
STM32_Project.zip