找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2048|回复: 1
收起左侧

STM32做的64通道数据采集程序

[复制链接]
ID:683662 发表于 2020-7-5 19:19 | 显示全部楼层 |阅读模式
STM32做的64通道数据采集电路  采样频率30hz 效果非常

单片机源程序如下:
  1. //4.4 Repeat-sequence mode

  2. //Sequence模式时可以设置多个采样通道。在最后一个通道加上EOS就表明的采样通道结束位置。中断允许只需要设置最后一个通道。

  3. //为了采样速率尽可能快,可设置MSC,此时当SHI上升沿触发第一次采样后,后面的采样在上一次采样结束后自动进行。

  4. #include <msp430x14x.h>
  5. #include "Config.h"                     //开发板配置头文件,主要配置IO端口信息
  6. //表区
  7. #define ADCOK 0x01           //B0为ADC12完成转换标志.
  8. unsigned char number_table[]={'0','1','2','3','4','5','6','7','8','9','.'};
  9. //unsigned char display_buffer[]={0x00,0x00,0x00,0x00,'\0'};
  10. unsigned char display_buffer[]={0x00,0x00,'\0'};
  11. unsigned char display_buffer2[]={0x00,'\0'};

  12. //*******************波特率***********300  600 1200 2400 4800 9600 19200 38400 76800 115200const
  13. //************************************[0]**[1]**[2]*[3]**[4]**[5]***[6]***[7]****[8]***[9]*
  14. unsigned char BaudrateUBR0[]       ={0x6D,0x36,0x1B,0x0D,0x06,0x03, 0xA0, 0xD0, 0x68, 0x45};
  15. unsigned const char BaudrateUBR1[] ={0x00,0x00,0x00,0x00,0x00,0x00, 0x01, 0x00, 0x00, 0x00};
  16. unsigned const char BaudrateUMCTL[]={0x22,0xD5,0x03,0x6B,0x6F,0x4A, 0xC0, 0x40, 0x40, 0x4A};
  17. unsigned int head[] ={0xAA,0x00};
  18. unsigned int tail[] ={0x55,0x00};


  19. unsigned char timp;     //全局位变量区
  20. unsigned char gbit;     //B0为ADC12完成转换标志.                          
  21. unsigned int ADC[8] ;   //ADC12读出数据数组
  22. unsigned char contralAD;

  23. //子程序声明
  24. void init (void);                                         //初始化
  25. void ADC12setup(void);                                    //ADC12初始化
  26. void BaudrateSetup(unsigned char U0);                     //UART0初始化
  27. void timer_A_setup(void);                                 //timer_A初始化
  28. void data_converter(unsigned char *p,unsigned int vaule); //数据变换
  29. void data_converter1(unsigned char *p,unsigned int vaule);//数据变换1
  30. void send_data(unsigned char *p);                         //串行口发送数组
  31. void send_adc12_data(unsigned int *p,unsigned int adcn);  //发送ADC12数据
  32. void send_adc12_xieyi(unsigned int *p,unsigned int adcn);  //发送ADC12协议
  33. void Adc12Open(unsigned char doit);


  34. //*************************************************************************
  35. //              串口0发送数据函数
  36. //*************************************************************************
  37. /*
  38. void Send_Byte(uchar data)
  39. {
  40.   while(!(IFG1&UTXIFG0));          //发送寄存器空的时候发送数据
  41.     U0TXBUF=data;
  42. }

  43. //*************************************************************************
  44. //              串口0发送字符串函数
  45. //*************************************************************************
  46. void Print_Str(uchar *s)
  47. {
  48.     while(*s != '\0')
  49.     {
  50.         Send_Byte(*s++);
  51.     }
  52. }

  53. */


  54. //******************************************************************************
  55. //发送ADC12数据
  56. //*p为数据区,adcn为数量
  57. /*
  58. void send_adc12_data(unsigned int *p)
  59. {
  60.   unsigned char result[18];
  61.     result[0]=0xAA;
  62.   result[1]  = (unsigned char)(p[0] >> 8);      //采样结果,对应板上VR电位器.
  63. result[2]  = (unsigned char)p[0];       //对应预留仪表放器电路,此路默认为空.
  64. result[3] = (unsigned char)(p[1]>> 8);
  65. result[4]  = (unsigned char)p[1];
  66. result[5]  = (unsigned char)(p[2] >> 8);
  67. result[6]= (unsigned char)p[2];
  68. result[7]  = (unsigned char)(p[3] >> 8);
  69. result[8]  = (unsigned char)p[3];
  70. result[9]  = (unsigned char)(p[4] >> 8);
  71. result[10]  = (unsigned char)p[4];
  72. result[11]  = (unsigned char)(p[5] >> 8);
  73. result[12]  = (unsigned char)p[5];
  74. result[13]  = (unsigned char)(p[6] >> 8);
  75. result[14]  = (unsigned char)p[6];
  76. result[15]  = (unsigned char)(p[7] >> 8);
  77. result[16]  = (unsigned char)p[7];
  78.     result[17]  = 0x55;
  79.        Print_Str(result);            //发送数据

  80. }
  81. */
  82. //******************************************************************************




  83. //******************************************************************************
  84. //串口接收中断
  85. //usart0 interrupt receive function  

  86. #pragma vector=UART1RX_VECTOR  
  87.   
  88. __interrupt void usart1_rx (void)  
  89. {     
  90.   while(RXBUF1 != 0)
  91. {
  92.     while(1);
  93. }
  94. ;
  95.   if(RXBUF1==0x43)//0x43开始,0x44停止采集
  96.   {
  97. LPM0_EXIT;
  98. ADC12setup();
  99. //send_adc12_data(ADC,8);
  100. while((gbit&ADCOK)==0);               //等待序列单次完成
  101.   gbit &= ~ADCOK;                       //清转换完成标志
  102.   

  103. }         
  104.    
  105.     if( RXBUF1 == 0x44 ){           //收到1时,led灯亮,并发送 "led is off"  
  106.          Adc12Open(100);
  107.      _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, Enable interrupts
  108.         }  
  109.       
  110. }

  111. //******************************************************************************
  112. //timer_A设置
  113. /*
  114. void timer_A_setup(void)
  115. {
  116. TACTL = TASSEL_2+MC_2;        //Timer A 时钟源先为SMCLK,增加方式
  117. // TACTL = TASSEL_1+MC_2;        //Timer A 时钟源先为ACLK,增加方式
  118.   TACCTL1 = OUTMOD_3;           //CCR1输出模式:PWM置位/复位
  119.   //TACCR1 = 0x0ffff;             //CCR1比较值
  120.   TACCR1 = 0xfffff;   
  121. }
  122. */

  123. //******************************************************************************
  124. //UART0初始化                 //8Mhz晶体程序不能用.
  125. /*
  126. void BaudrateSetup(unsigned char U0)      
  127. {   
  128. unsigned int i;
  129. if(U0>5)                     //当U0>5时,启用XT2
  130. {
  131.   BCSCTL1 &= ~XT2OFF;         //启动XT2,
  132. do
  133.   {IFG1 &= ~OFIFG;           //清OSCFault标志
  134.      for(i=0xFF;i>0;i--);    //延时等待
  135.   }
  136.   while((IFG1 & OFIFG) != 0); //查OSCFault,为0时转换完成
  137. BCSCTL2 |= SELS;             //SMCLK为XT2
  138. }
  139. //UART0
  140. P1OUT=0x00;
  141. if(U0>5){UTCTL0=SSEL1;}      // Clock Source:SMCLK
  142. else{UTCTL0=SSEL0;}          // Clock Source:ACLK
  143. UCTL0 &= ~SWRST;             // SWRST复位, USART允许
  144. UCTL0=CHAR;                  // 8bit
  145. ME1|=UTXE0 + URXE0;          // Enable Tx0,Rx0
  146. IE1|=URXIE0;                 // RX enable
  147. UBR00=BaudrateUBR0[U0];      // 低位分频器因子
  148. UBR10=BaudrateUBR1[U0];      // 高位分频器因子        
  149. UMCTL0=BaudrateUMCTL[U0];    // 波特率调整因子
  150. P3SEL |= 0x30;               // 将P3.4,5使用外围模块 = USART0 TXD/RXD
  151. P3DIR |= 0x10;               // 将P3.4设为输出(发),P3.5默认为输入(收)
  152. }
  153. */
  154. //*************************************************************************
  155. //               MSP430串口初始化
  156. //*************************************************************************
  157. void UART_Init()
  158. {
  159.   U1CTL|=SWRST + CHAR;                //复位SWRST,8位数据模式
  160.   U1TCTL|=SSEL1;                      //SMCLK为串口时钟
  161.   U1BR1=baud_h;                       //BRCLK=8MHZ,Baud=BRCLK/N
  162.   U1BR0=baud_l;                       //N=UBR+(UxMCTL)/8
  163.   U1MCTL=0x00;                        //微调寄存器为0,波特率9600bps
  164.   ME1|=UTXE1;                         //UART0发送使能
  165.   ME1|=URXE1;                         //UART0接收使能
  166.   U1CTL&=~SWRST;
  167.   IE1|=URXIE1;                        //接收中断使能位
  168.   
  169.   P3SEL|= BIT4 + BIT5;                //设置IO口为第二功能模式,启用UART功能
  170.   P3DIR|= BIT4;                       //设置TXD0口方向为输出
  171. }


  172. //*************************************************************************
  173. //              ADC Setup函数
  174. //*************************************************************************
  175. //4.4 Repeat-sequence mode

  176. //Sequence模式时可以设置多个采样通道。在最后一个通道加上EOS就表明的采样通道结束位置。中断允许只需要设置最后一个通道。

  177. //为了采样速率尽可能快,可设置MSC,此时当SHI上升沿触发第一次采样后,后面的采样在上一次采样结束后自动进行。
  178. void ADC12setup(void)
  179. {
  180.    P6SEL |= 0xff;                        //使用A/D通道 A0,A1,A2,...,A7
  181.   //ADC12CTL0 = ADC12ON+MSC+SHT0_8;           // Turn on ADC12, extend sampling time

  182.                                             // to avoid overflow of results
  183. ADC12CTL0 = ADC12ON+MSC+SHT0_0+SHT0_1+SHT0_8+SHT1_8+SHT1_5+SHT1_6+SHT1_7+SHT1_8;
  184.    
  185.     //ADC12CTL1 = SHP+CONSEQ              // Use sampling timer, repeated sequence
  186.   ADC12CTL1 = ADC12SSEL_0+SHP+CONSEQ_3+ADC12DIV_7 ;      //SAMPCON信号选为采样定时器输出               
  187.                                         // Use sampling timer, repeated sequence

  188.   ADC12MCTL0 = INCH_0;                      // ref+=AVcc, channel = A0

  189.   ADC12MCTL1 = INCH_1;                      // ref+=AVcc, channel = A1

  190.   ADC12MCTL2 = INCH_2;                      // ref+=AVcc, channel = A2

  191.   ADC12MCTL3 = INCH_3;                  // ref+=AVcc, channel = A3, end seq.
  192.   
  193.   ADC12MCTL4 = INCH_4;                      // ref+=AVcc, channel = A0

  194.   ADC12MCTL5 = INCH_5;                      // ref+=AVcc, channel = A1

  195.   ADC12MCTL6 = INCH_6;                      // ref+=AVcc, channel = A2

  196.   ADC12MCTL7 = INCH_7+EOS;                  // ref+=AVcc, channel = A3, end seq.
  197.   
  198.   ADC12IE = 0x08;                           // Enable ADC12IFG.3
  199.   
  200.    ADC12CTL0 |= ENC;                         // Enable conversions

  201.    ADC12CTL0 |= ADC12SC;                     // Start conversion

  202.   _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, Enable interrupts
  203.   
  204.   

  205. }
  206. //****************************************************************************  
  207. //打开或关闭ADC12模块  
  208. //doit: 0:打开    100:关闭  
  209. //****************************************************************************/  
  210. void Adc12Open(unsigned char doit)   
  211. {   
  212.     if(doit==0)   
  213.     {   
  214.         ADC12CTL0 |= ADC12ON;   
  215.         ADC12CTL0 |= ENC;   //允许转换   
  216.     }   
  217.     else if(doit==100)   
  218.     {   
  219.         ADC12CTL0 &= ~ADC12ON;  //不允许转换   
  220.         ADC12CTL0 &= ~ENC;   
  221.     }   
  222. }   
  223. //*************************************************************************
  224. //         ADC 中断函数
  225. //*************************************************************************

  226. #pragma vector=ADC12_VECTOR

  227. __interrupt void ADC12ISR (void)

  228. {

  229.   static unsigned int index = 0;


  230. ADC[0] = ADC12MEM0;             // Move A0 results, IFG is cleared

  231. ADC[1] = ADC12MEM1;             // Move A1 results, IFG is cleared

  232. ADC[2] = ADC12MEM2;             // Move A2 results, IFG is cleared

  233. ADC[3] = ADC12MEM3;             // Move A3 results, IFG is cleared

  234. ADC[4] = ADC12MEM4;             // Move A0 results, IFG is cleared

  235. ADC[5] = ADC12MEM5;             // Move A1 results, IFG is cleared

  236. ADC[6] = ADC12MEM6;             // Move A2 results, IFG is cleared

  237. ADC[7] = ADC12MEM7;             // Move A3 results, IFG is cleared





  238. gbit |= ADCOK;           //置标志,表示ADC采样完成.
  239. send_adc12_xieyi(head,1);
  240. send_adc12_data(ADC,8);
  241. send_adc12_xieyi(tail,1);
  242. //ADC12CTL0 = ~ENC;
  243. //TXBUF0 = 0x55;



  244.   //index = (index+1)%Num_of_Results;         // Increment results index, modulo; Set Breakpoint here

  245. }





  246. void main(void)
  247. {
  248.    init();
  249. // Mainloop
  250.   while(1)                             
  251.   {
  252.   //LPM0;
  253.    ADC12CTL0 |= ADC12SC;                     // Start conversion

  254.   _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, Enable interrupts
  255.   _NOP();
  256.   }
  257. }
  258. //******************************************************************************
  259. //MCU初始化
  260. void init(void)
  261. {
  262.   WDTCTL = WDTPW + WDTHOLD;             // 停止WDT
  263. // timer_A_setup();                      //timer_A初始化
  264.   //Clock_Init();                       //系统时钟设置
  265.   //P1DIR=0x01;P1OUT=0x0f;                //LED设置
  266.   //BaudrateSetup(5);                    //设置波特率 9600
  267.    //Print_Str("DM430-L Board UART Test...\n");             //发送字符串测试
  268.                                 // 全局中断使能
  269.   //ADC12setup();
  270.     //Clock_Init();                       //系统时钟设置
  271.   Clock_Init_Inc;
  272.     //LED8 =0xff;                         //关灭所有LED
  273.    UART_Init();
  274.    _EINT();
  275. }

  276. void data_converter(unsigned char *p,unsigned int value)    //数据变换
  277. {
  278.   //unsigned int m,n,j=0;
  279.   //p[0]=number_table[value/1000];
  280.   p[0]=(unsigned char)(value >> 8);
  281. // m=value%1000;
  282.   //p[1]=number_table[m/100];
  283.   p[1]=(unsigned char)value ;
  284.   //n=m%100;
  285.   //p[2]=number_table[n/10];
  286.   //j=n%10;
  287.   //p[3]=number_table[j/1];
  288. }

  289. //******************************************************************************
  290. void data_converter1(unsigned char *p,unsigned int value)    //数据变换
  291. {
  292. p[0]=(unsigned char)value ;
  293. }
  294. //******************************************************************************
  295. //串行口发送数组
  296. void send_data(unsigned char *p)
  297. {unsigned int n;
  298. //timp=RXBUF0;
  299. for(n=0;p[n]!='\0';n++)
  300.    {
  301.     while ((IFG1 & UTXIFG1) == 0); // USART0发送UTXIFG0=1,表示UTXBUF准备好发送一下字符
  302.     TXBUF1 = p[n];
  303.    }
  304. }


  305. //******************************************************************************
  306. //发送ADC12数据
  307. //*p为数据区,adcn为数量
  308. void send_adc12_data(unsigned int *p,unsigned int adcn)
  309. {
  310. unsigned int j;
  311. for(j=0;j<adcn;j++)
  312.    {
  313.      //if(j==0)
  314.      //{
  315.        data_converter(display_buffer,p[j]);  //数据变换
  316.        send_data(display_buffer);            //发送数据
  317.    // }
  318.     // else
  319.     // {
  320.     //   data_converter(display_buffer,p[j]);  //数据变换
  321.     //   send_data(display_buffer);            //发送数据
  322.     // }     
  323.     }
  324. }
  325. //******************************************************************************
  326. //******************************************************************************
  327. //发送ADC12数据头AA 和 尾55
  328. //*p为数据区
  329. void send_adc12_xieyi(unsigned int *p,unsigned int adcn)
  330. {
  331.    unsigned int j;
  332.    for(j=0;j<adcn;j++)
  333.    {
  334.        data_converter1(display_buffer2,p[j]);  //数据变换
  335.        send_data(display_buffer2);            //发送数据
  336.    }
  337. }
  338. //******************************************************************************
复制代码
51hei.png
所有资料51hei提供下载:
AD_Mx_Seq_UART1.rar (28.72 KB, 下载次数: 17)

评分

参与人数 1黑币 +20 收起 理由
yanyuwei + 20 很给力!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2020-7-5 19:46 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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