找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7454|回复: 0
打印 上一主题 下一主题
收起左侧

STM8L的DMA详解 含例程

[复制链接]
跳转到指定楼层
楼主
ID:140343 发表于 2016-10-10 00:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM8L有DMA功能,STM8S没有这个功能.DMA用于传输数据,可以把内存中的数据(比如一个存放数据的数组),传递给外设(比如可以将数据传递到USART的发送数据寄存器),当然也可以反向,从外设的寄存器传递给内存,DMA的第四个通道还具有,将数据从内存传递到内存的功能.传递数据时,不占用CPU资源.

如上图,STM8L拥有四个DMA通道,每个通道都可以响应DMA请求,独立传送数据.如果四个通道同时收到DMA请求,DMA控制器会根据软件优先级和硬件优先,决定响应的先后顺序.

上图是支持DMA传输数据的外设,从上图还可以看到具体每个外设对应哪一个DMA通道,这个对编程很重.


上图是DMA的配置流程,基本的配置如下:
①配置外设寄存器地址
②配置内存寄存器地址
③配置传输数据的字节数
④设置通道优先级
⑤设置数据传输方向,是否自动连续传输,传输数据是16位还是8位,
⑥使能DMA通道
⑦是DMA通道总开关

本例程,使用DMA传送数据到USART的发送寄存器,周期性的重置DMA,重新发送数据。



  1. /*硬件连接*/

  2. // PC3(TX)---->

  3. /****************************************************************************************

  4. *开发环境:IAR for stm8 v6.5.3

  5. *硬件平台:STM8L-DISCOVERY

  6. *功能说明:使用DMA通道1传送数据到USART的发送寄存器 USART1_DR,周期性的发送数组中的数据

  7. *         对比.

  8. *作    者:茗风

  9. ****************************************************************************************/

  10. #include"iostm8l152c6.h"

  11. #include"stdbool.h"

  12. #include"stdint.h"


  13. #define  TXBUF_SIZE           9

  14. #define  RXBUF_SIZE           25

  15. #define  USART1_DR_ADRESS     0x5231


  16. bool bTX_finished=false;

  17. bool bRX_finished=false;//串口接收完一帧数据标志位

  18. uint8_t ui8TX_number = 0;

  19. uint8_t ui8RX_counter=0;

  20. uint8_t ui8TX_buffer[TXBUF_SIZE]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99};

  21. uint8_t ui8RX_buffer[RXBUF_SIZE];

  22. /******************************************************************************************************

  23. *  名    称:void delay_10ms(uint8_t x_ms)

  24. *  功    能:延时10ms

  25. *  入口参数:无

  26. *  出口参数:无

  27. *  说    明:

  28. *  范    例:无

  29. ******************************************************************************************************/

  30. void delay_100ms(void)

  31. {

  32.   uint8_t i,j;

  33.   for(i=0;i<255;i++)//2*255个指令周期

  34.     for(j=0;j<255;j++);//2*255个指令周期

  35.   //delay_10ms共消耗 x_ms*2*255+2*x_ms个指令周期  

  36.   //255*2*255+2*255=130610us=130ms

  37.   //此延时函数,延时时间为130ms

  38.   //16M/8/2=1M 一个指令周期为1us

  39. }

  40. /******************************************************************************************************

  41. *  名    称:void GPIO_Init(void)

  42. *  功    能:初始化PC7为高速推挽输出

  43. *  入口参数:无

  44. *  出口参数:无

  45. *  说    明:测量系统时钟频率的IO,测量到的频率是:目标时钟源/2/6

  46. *  范    例:无

  47. ******************************************************************************************************/

  48. void GPIO_Init(void)

  49. {

  50.    PC_CR1_C17  =1;//推挽输出

  51.    PC_CR2_C27  =1;//高速输出

  52.    PC_DDR_DDR7 =1;//PC4输出

  53. //   PC_ODR_ODR7 =0;//输出低电平

  54. }

  55. /******************************************************************************************************

  56. * 名             称:void UART_Init(void)

  57. * 功            能:UART定时器初始化系统

  58. * 入口   参数:无

  59. * 出口   参数:无

  60. * 说       明:UART初始化为 9600 1 8 n

  61. * 范      例:无

  62. ******************************************************************************************************/

  63. void UART_Init(void)

  64. {

  65.     /*********************************/

  66.     PC_DDR_DDR2 =0;//输入

  67.     PC_CR1_C12  =1;//上拉输入

  68.     PC_CR2_C22 =0;

  69.    

  70.     PC_ODR_ODR3 =1;

  71.     PC_CR1_C13  =1;//推挽输出

  72.     PC_CR2_C23  =1;//输出摆率10M   

  73.     PC_DDR_DDR3 =1;//输出高电平,TX空闲状态为高电平,如果不设置,会莫名奇妙的发送0x00

  74.    


  75.     CLK_PCKENR1_PCKEN15=1;//开启USART外设时钟

  76.    

  77.     //开启引脚的UART功能

  78.     //00: USART1_TX on PC3 and USART1_RX on PC2

  79.     //01: USART1_TX on PA2 and USART1_RX on PA3

  80.     //10: USART1_TX on PC5 and USART1_RX on PC6

  81.     SYSCFG_RMPCR1_USART1TR_REMAP =0;//PC2,PC3

  82.     //如果需要使用其他引脚作为串口发送接收引脚,请在这里选择

  83.    

  84.    

  85.     //设置串口工作方式

  86.     USART1_CR1_M =0;//1 start bit,8 data bit,n stop bit

  87.     USART1_CR3_STOP0=0;USART1_CR3_STOP1=0;//1 stop bit

  88.     //设置波特率

  89.     //波特率设置为9600

  90.     // 2000000/9600=208    //2000000是此时系统的主时钟频率,默认8分频,16M/8=2M

  91.     //208(DEC)=00D0(HEX)

  92.     USART1_BRR2 =0x00;//the BRR2 should be programmed before BRR1

  93.     USART1_BRR1 =0x0D;

  94.     USART1_CR5_DMAT=1;// DMA mode is enabled for transmission.

  95. //    USART1_CR2_TEN=0;//使能发送

  96. //    USART1_CR2_TIEN=0;//打开发送中断

  97.     USART1_CR2_REN=1;//使能接收

  98.     USART1_CR2_RIEN=1;//打开接收中断

  99. }

  100. /******************************************************************************************************

  101. *  名    称:void DMA_Config(void)

  102. *  功    能:启用DMA

  103. *  入口参数:无

  104. *  出口参数:无

  105. *  说    明:STM8L152C6属于中等容量MCU,只有一路DAC输出,输出引脚为PF0

  106. *  范    例:无

  107. ******************************************************************************************************/

  108. void DMA_Config(void)

  109. {

  110.   //------打开DAM时钟------

  111.   CLK_PCKENR2_PCKEN24=1;

  112.   

  113.   //------设置传送的字节数,------

  114.   DMA1_C1NDTR=9;  

  115.   

  116.   //------设置通道优先级------

  117.   DMA1_C1SPR_PL0=0;DMA1_C1SPR_PL1=1;


  118.   //------设置传送方向------

  119.   DMA1_C1CR_DIR=1;  

  120. /*  0: Transfer from the peripheral to the memory.

  121.    1: Transfer from the memory to the peripheral.*/



  122.   //------设置模式------  

  123.   DMA1_C1CR_CIRC=0;

  124. /* Auto-reload mode

  125.    0: Circular mode disabled.

  126.    1: Circular mode enabled.   */


  127.   //------设置增还是减地址------   

  128.   DMA1_C1CR_MINCDEC=1;

  129. /*  0: Decrement mode.

  130.     1: Increment mode.*/


  131.   //------设置传送数据位数------

  132.   DMA1_C1SPR_TSIZE=0;

  133. /*  0: 8-bit mode

  134.     1: 16-bit mode */

  135.   

  136.     //------设置DMA通道1外设地址------

  137.   DMA1_C1PARH=(uint8_t)((uint16_t)USART1_DR_ADRESS >> (uint8_t)8);

  138.   DMA1_C1PARL=(uint8_t)USART1_DR_ADRESS;

  139.    

  140.   //------设置DMA通道1内存地址------

  141.   DMA1_C1M0ARH=(uint8_t)((uint16_t)&ui8TX_buffer >> (uint8_t)8);

  142.   DMA1_C1M0ARL=(uint8_t)&ui8TX_buffer;

  143.   

  144.   DMA1_C1CR_EN=1;

  145.   

  146.   DMA1_GCSR_GEN=1;

  147.   

  148. }

  149. void main(void)

  150. {

  151. //  GPIO_Init();

  152.   DMA_Config();

  153.   UART_Init();

  154.   asm("rim");               //enable interrupts

  155.   while(1)

  156.   {

  157.     ui8TX_number=9;

  158.     USART1_CR2_TEN=1;//打开发送

  159.     delay_100ms();

  160.     delay_100ms();

  161.     delay_100ms();

  162.     delay_100ms();

  163.     DMA1_C1CR_EN=0;

  164.     DMA1_C1NDTR=9;

  165.     DMA1_C1CR_EN=1;


  166. //    asm("wfi");

  167.   }

  168. }

  169. /*************************************************************************************************** ***

  170. * 名 称: UART_OnTx()

  171. * 功 能: UART的Tx事件处理函数

  172. * 入口参数:无

  173. * 出口参数:无

  174. * 说 明:发送ui8TX_buffer数组中的数据,发送完成后,置位bTX_finished标志位,下一次进入中断后关闭发送

  175. * 范 例:无

  176. ******************************************************************************************************/


  177. #pragma vector=USART_T_TXE_vector

  178. __interrupt void USART_TX_ISR (void)

  179. {

  180.   static uint8_t cnts=0;

  181.   if(bTX_finished && USART1_SR_TC==1)

  182.   {

  183.     bTX_finished=false;

  184.     USART1_CR2_TIEN=0;//关闭发送中断

  185.     USART1_CR2_TEN=0;//关闭发送

  186.   }

  187.   else if(USART1_SR_TC==1)

  188.   {

  189.     USART1_DR=ui8TX_buffer[cnts++];

  190.     if(cnts==ui8TX_number)

  191.     {

  192.       cnts=0;

  193.       bTX_finished=true;

  194.     }

  195.   }

  196. }

  197. /******************************************************************************************************

  198. * 名               称: UART_OnRx()

  199. * 功         能: UART的Tx事件处理函数

  200. * 入口           参数:无

  201. * 出口           参数:无

  202. * 说               明:

  203. * 范              例:无

  204. ******************************************************************************************************/

  205. #pragma vector=USART_R_RXNE_vector

  206. __interrupt void USART_RX_ISR(void)

  207. {

  208.   static uint8_t ui8RX_temp=0;

  209.   if(USART1_SR_RXNE==1)

  210.   {

  211.     ui8RX_temp = USART1_DR;

  212.   }

  213. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表