bsp_DMAusart1.h

  1. #ifndef __BSP_DMAUSART1_H
  2. #define __BSP_DMAUSART1_H
  3. //-------------------------------------------------------------------
  4. #include "stm32f10x.h"
  5. #include <string.h>
  6. //-------------------------------------------------------------------
  7. #define USART1_REC_LEN 58 //定义最大接收字节数 58
  8. typedef struct
  9. {
  10. uint8_t Tx_buf[USART1_REC_LEN]; //发送缓冲区
  11. uint8_t Tx_len; //发送长度
  12. uint8_t Rx_buf[USART1_REC_LEN]; //接收缓冲区
  13. uint8_t Rx_len; //接收长度
  14. uint8_t Rx_end_flag; //接收完成标志
  15. uint8_t Rx_time_start; //计时启动标志
  16. uint16_t Rx_time; //1祯数据接收时长(mSec)
  17. }USART1_DEF;
  18. extern USART1_DEF OneUART;
  19. //-------------------------------------------------------------------
  20. void USART1_Init(uint32_t BAND,uint8_t *SendAddres,uint8_t *RecAddres,uint8_t len);
  21. void DMA_USART1RxTx_Init(uint8_t *SendAd,uint8_t *RecAddres,uint8_t len);
  22. void NVIC_USART1_Configuration(void);
  23. void USART1_SendChar(u8 t);
  24. void USART_printf(USART_TypeDef* USARTx, uint8_t *Data,...);
  25. void USART1_SendString(void* buffer, uint16_t size);
  26. void USART1_Encryption_SendString(void* buffer, uint16_t size);
  27. uint16_t USART1_DMASendString(void* buffer, uint16_t size);
  28. uint16_t USART1_Encryption_DMASendString(void* buffer, uint16_t size);
  29. #endif /* __USART1_H */

bsp_DMAusart1.c

  1. #include "bsp_DMAusart1.h"
  2. USART1_DEF OneUART;
  3. /**
  4. * @brief USART1初始化
  5. * @param BAND,波特率(2400,4800,9600,38400,115200)
  6. * Send_pf,发送数据缓冲区
  7. * Rec_pf,接收数据缓冲区
  8. * buf_len,接收数据缓冲区长度
  9. * @retval 无
  10. */
  11. void USART1_Init(uint32_t BAND,uint8_t *Send_pf,uint8_t *Rec_pf,uint8_t buf_len)
  12. {
  13. GPIO_InitTypeDef GPIO_InitStructure;
  14. USART_InitTypeDef USART_InitStructure;
  15. /* config USART1 clock */
  16. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOB, ENABLE);
  17. /* USART1 GPIO config */
  18. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能端口重映射
  19. /* Configure USART1 Tx (PB6) as alternate function push-pull */
  20. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  22. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  23. GPIO_Init(GPIOB, &GPIO_InitStructure);
  24. /* Configure USART1 Rx (PB7) as input floating */
  25. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  26. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  27. GPIO_Init(GPIOB, &GPIO_InitStructure);
  28. /* RS485,Tx/Rx Control PB5 */
  29. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  30. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  31. GPIO_Init(GPIOB, &GPIO_InitStructure);
  32. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  33. GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
  34. /* USART1 mode config */
  35. USART_InitStructure.USART_BaudRate = BAND;
  36. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  37. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  38. USART_InitStructure.USART_Parity = USART_Parity_No ;
  39. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  40. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  41. USART_Init(USART1, &USART_InitStructure);
  42. USART_Cmd(USART1, ENABLE);
  43. USART_ClearFlag(USART1, USART_FLAG_TC); //清发送完成标志
  44. USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启空闲中断
  45. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断
  46. USART_ITConfig(USART1, USART_IT_TC, ENABLE); //开启发送完成中断
  47. NVIC_USART1_Configuration();
  48. DMA_USART1RxTx_Init(Send_pf,Rec_pf,buf_len);//DMA初始化
  49. }
  50. /**
  51. * @brief 配置USART1中断
  52. * @param
  53. * @retval 无
  54. */
  55. static void NVIC_USART1_Configuration(void)
  56. {
  57. NVIC_InitTypeDef NVIC_InitStructure;
  58. /* Configure the NVIC Preemption Priority Bits */
  59. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  60. /* Enable the USARTy Interrupt */
  61. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //开启接收完成中断
  62. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  63. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  64. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  65. NVIC_Init(&NVIC_InitStructure);
  66. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  67. /* Enable the USARTy Interrupt */
  68. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;//开启发送完成中断
  69. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  70. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  71. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  72. NVIC_Init(&NVIC_InitStructure);
  73. }
  74. /**
  75. * @brief DMA_USART1初始化
  76. * @param Send_pf,发送数据缓冲区
  77. * Rec_pf,接收数据缓冲区
  78. * buf_len,接收数据缓冲区长度
  79. * @retval 无
  80. */
  81. static void DMA_USART1RxTx_Init(uint8_t *Send_pf,uint8_t *Rec_pf,uint8_t buf_len)
  82. {
  83. DMA_InitTypeDef DMA_InitStructure;
  84. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  85. DMA_Cmd(DMA1_Channel5,DISABLE); //关闭DMA
  86. DMA_DeInit(DMA1_Channel5); //恢复默认
  87. DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&USART1->DR; //设置串口发送数据寄存器
  88. DMA_InitStructure.DMA_MemoryBaseAddr=(u32)Rec_pf; //设置发送缓冲区首地址
  89. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //设置外设位目标,内存缓冲区 <- 外设寄存器
  90. DMA_InitStructure.DMA_BufferSize=buf_len; //需要发送的字节数,这里其实可以设置为0,因为在实际要发送的时候,会重新设置次值
  91. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不递增
  92. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存递增
  93. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节宽度
  94. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存字节宽度
  95. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //正常模式
  96. DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //高优先级
  97. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //关闭内存到内存的DMA模式
  98. DMA_Init(DMA1_Channel5,&DMA_InitStructure); //配置DMA1的6通道
  99. DMA_Cmd(DMA1_Channel5,ENABLE); //使能DMA
  100. DMA_DeInit(DMA1_Channel4);
  101. DMA_InitStructure.DMA_PeripheralBaseAddr= (u32)&USART1->DR; //初始化外设地址
  102. DMA_InitStructure.DMA_MemoryBaseAddr=(u32)Send_pf; //内存地址
  103. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据来源
  104. DMA_InitStructure.DMA_BufferSize=0; //发送长度为0
  105. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不递增
  106. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存递增
  107. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节宽度
  108. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存字节宽度
  109. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //正常模式
  110. DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //高优先级
  111. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //关闭内存到内存的DMA模式
  112. DMA_Init(DMA1_Channel4,&DMA_InitStructure); //配置DMA1的7通道
  113. DMA_Cmd(DMA1_Channel4,ENABLE); //使能DMA
  114. USART_ITConfig(USART1, USART_DMAReq_Tx, ENABLE); //开启中断USART_DMAReq_Tx
  115. USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //开启接收接收
  116. USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //开启接收发送
  117. // DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); //配置DMA发送完成后产生中断
  118. }
  119. /**
  120. * @brief USART1_DMA发送完成中断
  121. * @param 无
  122. * @retval 无
  123. */
  124. void DMA1_Channel4_IRQHandler(void)
  125. {
  126. if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET)
  127. {//发送完成中断
  128. DMA_ClearFlag(DMA1_FLAG_TC4);
  129. //GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  130. }
  131. }
  132. /**
  133. * @brief USART1串口接收中断
  134. * @param 无
  135. * @retval 无
  136. */
  137. void USART1_IRQHandler(void) //串口1中断服务程序
  138. {
  139. static uint8_t LEN=0;
  140. uint8_t Clear=Clear,tmp;
  141. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  142. {//接收中断
  143. OneUART.Rx_buf[LEN++]= USART1->DR; //读取接收到的数据
  144. LEN= (LEN < USART1_REC_LEN)?LEN:0;
  145. }else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
  146. {//空闲中断,1桢数据接收完毕
  147. Clear=USART1->SR; //读SR寄存器
  148. Clear=USART1->DR; //读DR寄存器,(先读SR,再读DR就是清除IDLE标志中断)
  149. OneUART.Rx_end_flag = 1; //接收完成标志
  150. DMA_Cmd(DMA1_Channel5,DISABLE);
  151. OneUART.Rx_len=USART1_REC_LEN-DMA_GetCurrDataCounter(DMA1_Channel5);
  152. DMA_SetCurrDataCounter(DMA1_Channel5,USART1_REC_LEN); //设置DMA缓冲区长度
  153. DMA_Cmd(DMA1_Channel5,ENABLE);
  154. }else if(USART_GetITStatus(USART1, USART_IT_TC) != RESET)
  155. {//发送完成中断
  156. USART_ClearITPendingBit(USART1, USART_IT_TC); //清除USART1发送完成中断标志
  157. DMA_ClearFlag(DMA1_FLAG_TC4); //清零标志位
  158. GPIO_ResetBits(GPIOB,GPIO_Pin_5); //发送完成,等待接收数据
  159. }
  160. }
  161. /**
  162. * @brief DMA_USART1数据发送
  163. * @param buffer,发送数据地址
  164. * size,发送数据长度
  165. * @retval size
  166. */
  167. uint16_t USART1_DMASendString(void* buffer, uint16_t size)
  168. {
  169. if(!size) return 0; //判断长度是否有效
  170. while(DMA_GetCurrDataCounter(DMA1_Channel4)); //检查DMA通道内是否还有数据
  171. if(buffer) //发送数据拷贝到发送缓存区
  172. memcpy(OneUART.Tx_buf, buffer,(size > 1024?1024:size));
  173. DMA_Cmd(DMA1_Channel4, DISABLE); //DMA发送数据要先关闭,设置发送数据长度 开启DMA
  174. DMA1_Channel4->CNDTR = size; //设置发送长度
  175. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  176. DMA_Cmd(DMA1_Channel4, ENABLE); //启动DMA发送
  177. return size;
  178. }
  179. /**
  180. * @brief DMA_USART1加密数据发送
  181. * @param buffer,发送数据地址
  182. * size,发送数据长度
  183. * @retval size
  184. */
  185. uint16_t USART1_Encryption_DMASendString(void* buffer, uint16_t size)
  186. {
  187. if(!size) return 0; //判断长度是否有效
  188. while(DMA_GetCurrDataCounter(DMA1_Channel4)); //检查DMA通道内是否还有数据
  189. if(buffer) //发送数据拷贝到发送缓存区
  190. {
  191. //encryption(buffer,size);//使能加密
  192. memcpy(OneUART.Tx_buf, buffer,(size > 1024?1024:size));
  193. }
  194. DMA_Cmd(DMA1_Channel4, DISABLE); //DMA发送数据要先关闭,设置发送数据长度 开启DMA
  195. DMA1_Channel4->CNDTR = size; //设置发送长度
  196. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  197. DMA_Cmd(DMA1_Channel4, ENABLE); //启动DMA发送
  198. return size;
  199. }
  200. /**
  201. * @brief USART1发送数据1个字节
  202. * @param dat,发送数据
  203. * @retval 无
  204. */
  205. void USART1_SendChar(u8 t)
  206. {
  207. USART_SendData(USART1,t);
  208. while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  209. while((USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET));//等待串口发送完毕
  210. }
  211. /**
  212. * @brief USART1发送字符串
  213. * @param dat,发送数据
  214. * @retval 无
  215. */
  216. void USART1_SendString(void* buffer, uint16_t size)
  217. {
  218. uint8_t i=0,*buf;
  219. buf=buffer;
  220. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  221. while(size--)
  222. {
  223. USART1_SendChar(buf[i++]);
  224. }
  225. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  226. }
  227. /**
  228. * @brief USART1加密发送字符串
  229. * @param dat,发送数据
  230. * @retval 无
  231. */
  232. void USART1_Encryption_SendString(void* buffer, uint16_t size)
  233. {
  234. uint8_t i=0,*buf;
  235. //encryption(buffer,size);
  236. buf=buffer;
  237. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  238. while(size--)
  239. {
  240. USART1_SendChar(buf[i++]);
  241. }
  242. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  243. }

bsp_tim3.h

  1. #ifndef __BSP_TIM3_H
  2. #define __BSP_TIM3_H
  3. #include "stm32f10x.h"
  4. void TIM3_Int_Init(u16 arr,u16 psc);
  5. #endif // __BSP_TIM3_H

bsp_tim3.c

  1. #include "bsp_tim3.h"
  2. extern uint16_t time;
  3. //void TIM3_Int_Init(u16 arr,u16 psc)
  4. //{
  5. // TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  6. // NVIC_InitTypeDef NVIC_InitStructure;
  7. // RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  8. //
  9. // TIM_TimeBaseStructure.TIM_Period = arr;
  10. // TIM_TimeBaseStructure.TIM_Prescaler =psc;
  11. // TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  12. // TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  13. // TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  14. //
  15. // TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
  16. // NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  17. // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  18. // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
  19. // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  20. // NVIC_Init(&NVIC_InitStructure);
  21. // TIM_Cmd(TIM3, ENABLE);
  22. //}
  23. void TIM3_Int_Init(u16 arr,u16 psc)
  24. {
  25. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  26. NVIC_InitTypeDef NVIC_InitStructure;
  27. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  28. //定时器TIM3初始化
  29. TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
  30. TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  31. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  32. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  33. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
  34. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
  35. TIM_ClearFlag(TIM3,TIM_IT_Update );
  36. //中断优先级NVIC设置
  37. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
  38. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
  39. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5; //从优先级3级
  40. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  41. NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
  42. TIM_Cmd(TIM3, ENABLE); //使能TIMx
  43. }
  44. //定时器3中断服务程序
  45. void TIM3_IRQHandler(void) //TIM3中断
  46. {
  47. static u16 mS_Cnt_0=0;
  48. static u16 mS_Cnt_1=0;
  49. static u16 mS_Cnt_2=0;
  50. static u16 mS_Cnt_3=0;
  51. static u16 mS_Cnt_4=0;
  52. if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
  53. // if(TIM2->SR&0X0001)//寄存器操作
  54. {
  55. TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志 ,库函数操作
  56. //---------------------------------------[2]
  57. time++;
  58. //---------------------------------------[5]
  59. }
  60. }
  61. // 延迟分钟函数
  62. uint8_t delayed(uint8_t minute)
  63. {
  64. // 1分钟的
  65. if(time == 6000 * minute)
  66. {
  67. time = 0;
  68. return 0;
  69. }
  70. }
  71. //void TIM3_IRQHandler(void) //TIM3中断
  72. //{
  73. // static uint16_t Sys_Cnt[5]={0};
  74. // if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
  75. // {
  76. // time++;
  77. // TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志 ,库函数操作 TIM_IT_Update
  78. // }
  79. //}
  80. //void BASIC_TIM_IRQHandler(void)
  81. //{
  82. // if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET )
  83. // {
  84. // time++;
  85. // TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update);
  86. // }
  87. //}

main.c

  1. /**********************
  2. 芯片:STM32F103C8T6
  3. 实现功能:
  4. 引脚:PC13
  5. ***********************/
  6. #include "stm32f10x.h"
  7. #include "bsp_DMAusart1.h"
  8. #include "bsp_tim3.h"
  9. uint16_t time=0;
  10. uint8_t time10 = 0;
  11. int main()
  12. {
  13. USART1_Init(115200, OneUART.Tx_buf, OneUART.Rx_buf, USART1_REC_LEN);
  14. USART1_DMASendString("time end!",sizeof("time end!"));
  15. //每次进入中断服务程序间隔时间为((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+7199)/72M)*(1+9999)=1秒
  16. //TIM3_Int_Init(9999, 71); // 1ms
  17. //TIM3_Int_Init(59999, 71); // 60ms
  18. //TIM3_Int_Init(59999, 7199); // 6s
  19. //TIM3_Int_Init(59999, 35999); // 30s
  20. while(1)
  21. {
  22. if(OneUART.Rx_end_flag)
  23. {
  24. if(OneUART.Rx_buf[0]== 0x01)
  25. {
  26. OneUART.Rx_buf[0] = 0x00;
  27. TIM3_Int_Init(59999, 35999); // 30s
  28. }
  29. if(OneUART.Rx_buf[0]== 0x02)
  30. {
  31. OneUART.Rx_buf[0] = 0x00;
  32. TIM_Cmd(TIM3, DISABLE);
  33. }
  34. }
  35. // 1分钟
  36. if(time == 2)
  37. {
  38. time = 0;
  39. // USART1_DMASendString("time end!",sizeof("time end!"));
  40. USART1_DMASendString("1分钟!",sizeof("1分钟!"));
  41. time10++;
  42. }
  43. // 10分钟
  44. if(time10 == 10)
  45. {
  46. time10 = 0;
  47. USART1_DMASendString("10分钟!", sizeof("10分钟!"));
  48. }
  49. }
  50. }

STM32_Project.zip