找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12081|回复: 13
收起左侧

用MSP430自带ADC做个简易示波器

  [复制链接]
ID:140725 发表于 2016-10-11 22:56 | 显示全部楼层 |阅读模式
  发现用msp430做简易示波器的不多,感觉430还不错
  msp430转换速率200KSPS,2系列16M,算是比较快的了吧,用的msp430f2274做的
  因为硬件比较简单,基本上是最小系统,程序应该通用的
  屏幕12864 (ST7920) 19264(KS0108),程序写的很乱,功能不全,但基本功能有了,而且基本上是东挪西借,呵呵
16303050vnv155xffxhx1v.jpg.thumb.jpg

163032oqswfxswsw55srzz.jpg.thumb.jpg


163034d86jskxzdreeg588.jpg.thumb.jpg
 

1630350bcgcdcgbccy7ynz.jpg.thumb.jpg
 

163037oan255nc5uoq265c.jpg.thumb.jpg
 

163039dtr56a5h64r4655s.jpg.thumb.jpg
163041ynpy7nczfq4t7gn4.jpg.thumb.jpg
 原理图没有画,前级衰减画上了,但没有装,直接进单片机。
没有画原理图,基本上是最小系统
LCD接口定义和按键都可以在程序中看出来原理图没有画,前级衰减画上了,但没有装,直接进单片机。
没有画原理图,基本上是最小系统
LCD接口定义和按键都可以在程序中看出来

开发工具用的ez430f2013。SPY-BI-WIRE,两线制JTAG,下载比较方便,呵呵
跟1系列区别应该不大,就是频率高点,一些外设不一样而已

12864液晶的主程序部分预览:
  1. #include<msp430f2274.h>
  2. #include"math.h"
  3. #include"font 3X6.h"
  4. #include"12864.c"
  5. #define S1 7
  6. #define S2 6
  7. #define S3 5
  8. #define S4 4
  9. #define S5 3

  10. #define   Num_of_Results   100
  11. static unsigned int results[Num_of_Results];
  12. unsigned char index = 0;


  13. void ADC_Init(void)
  14. {
  15.   ADC10CTL1 = INCH_7 + CONSEQ_2;                     //Repeat single channel
  16.   ADC10CTL0 = ADC10SHT_3 + MSC + ADC10ON + ADC10IE;   //ADC10ON , Interrupt enale  
  17.   ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
  18.   ADC10AE0 |= 0X80;
  19. }
  20. /*******************测量电压峰峰值********************/
  21. void Disp_Vpp(unsigned char hang,unsigned char lie,unsigned int VPP)
  22. {
  23.   float real_vpp;
  24.   unsigned int Uintvpp;
  25.   unsigned char ge,shi,bai;   //,i;
  26.   real_vpp = (VPP*3.3)/1024;
  27.   Uintvpp = real_vpp*100;
  28.   bai = Uintvpp/100%10;
  29.   shi = Uintvpp/10%10;
  30.   ge = Uintvpp%10;
  31.   
  32.   Draw_Font(hang,lie+0,font3x6+9+bai*3);
  33.   Draw_Font(hang,lie+3,font3x6+3);
  34.   Draw_Font(hang,lie+6,font3x6+9+shi*3);
  35.   Draw_Font(hang,lie+10,font3x6+9+ge*3);
  36.   
  37. }

  38. void Measure_Vol(void)
  39. {
  40.    unsigned int Max_voltage = 0,Min_voltage = 1024;
  41.    unsigned int c;
  42. //   float Real_Voltage;
  43.    uchar i,e;
  44.    
  45.    for(i=0;i<100;i++)
  46.    {
  47.       if(results[i] > Max_voltage)
  48.         Max_voltage = results[i];
  49.       else
  50.         if(results[i] < Min_voltage)
  51.           Min_voltage = results[i];
  52.    }
  53.    
  54.    c = Max_voltage - Min_voltage;
  55.    e++;
  56.    if(e > 5)
  57.    {
  58.      Disp_Vpp(10,102,Max_voltage);
  59.      Disp_Vpp(17,102,Min_voltage);
  60.      Disp_Vpp(24,102,c);
  61.      e = 0;
  62.    }
  63. }

  64. /********************测量电压峰峰值********************/


  65. /********************ADC中断服务函数********************/

  66. #pragma vector = ADC10_VECTOR
  67. __interrupt void ADC10ISR (void)
  68. {

  69.   results[index] = ADC10MEM;               // Move results
  70.   index++;
  71.   if(index == 100)
  72.   ADC10CTL0 &=~ ADC10IE;   

  73. }

  74. main()
  75. {
  76.   uchar y1=0,y2=0,i,j;          //y坐标
  77.   uchar TimeDiv = 3;
  78.   WDTCTL = WDTPW + WDTHOLD;
  79.   P1DIR = 0X00;                //P1.7--P1.3设为输入,检测按键
  80.   DCOCTL  = CALBC1_16MHZ;
  81.   BCSCTL1 = CALBC1_16MHZ;
  82.   Ini_lcd();
  83.   Clear_GDRAM();
  84.   Draw_PM(tab);
  85.   ADC_Init();
  86.   _EINT();
  87.   while(1)
  88.   {

  89. /**********************检测按键**************************/
  90.     if(!(P1IN&(0x01<<S2)))
  91.     {
  92.       while(!(P1IN&(0x01<<S2)));
  93.       TimeDiv--;
  94.       ADC10CTL0 &=~ ENC;
  95.       ADC10CTL0 = ADC10SHT_0;
  96.       ADC10CTL1 = INCH_7 + CONSEQ_2;                     //Repeat single channel
  97.       ADC10CTL0 = TimeDiv*0x800 + MSC + ADC10ON + ADC10IE;   //ADC10ON , Interrupt enale  
  98.       ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
  99.       if(TimeDiv == 0) TimeDiv = 4;
  100.     }
  101.    
  102.     if(index == 100)                           //测完99次再显示
  103.   {
  104.     index = 0;
  105.     for(i=0;i<=99;i++)                      //显示时把99次测量的值画点在12864上   
  106.     {
  107.       y1 = y2;
  108.       y2 = 61 - (results[i]/17);            //17表示 满量程1024除以60个点
  109.       LCD_Set_Dot1(i,y2);
  110.       
  111.       if((abs(y2 - y1)>=3)&&(i!=0))        //如果下一点的纵坐标比前一个点的纵坐标大3,为了看起来连续,两个点画线
  112.       Lcd_DrawLine_Y(y1,y2,i);
  113.     }
  114.     Measure_Vol();                         //测量最大值最小值     
  115.     Delay_Nms(200);                       //等待1秒左右时间

  116. /**********************检测按键S1**************************/
  117.       while(!(P1IN&(0x01<<S1)));                // FREEZE,锁定屏幕
  118. /**********************检测按键S1**************************/

  119.    
  120.     for(i=0;i<=99;i++)                    //显示过后删除,不能清屏,因为清屏的话看起来屏幕会闪烁
  121.     {
  122.       y1 = y2;
  123.       y2 = 61 - (results[i]/17);
  124.       if((! ((i%10 == 9)&&(y2%10 == 1) ||(i==0) )))
  125.       LCD_ReSet_Dot1(i,y2);
  126.       
  127.       if((abs(y2 - y1)>=3)&&(i!=0))
  128.       Lcd_ReDrawLine_Y(y1,y2,i);
  129.       
  130.     }
  131.    
  132.       for(j=1;j<100;j=j+2)                                  //画中心X,Y轴
  133.       {
  134.         LCD_Set_Dot1(49,j);
  135.         LCD_Set_Dot1(j,31);
  136.         for(i=1;i<62;i=i+10)                                
  137.         {
  138.           if( ( ((j%10 == 9)||j==1))&&(i%10 == 1) )           //保存背景的点
  139.           LCD_Set_Dot1(j,i);
  140.         }
  141.       }
  142.    ADC10CTL0 |= ADC10IE;   
  143.   }
  144.   
  145.   }
  146. }
复制代码
19264液晶屏:
  1. #include<msp430f2274.h>
  2. #include"math.h"
  3. #include"font 3X6.h"
  4. #include"19264-KS0108.c"
  5. #include"ADC.c"


  6. #define S1 7
  7. #define S2 6
  8. #define S3 5
  9. #define S4 4
  10. #define S5 3

  11. void main(void)
  12. {
  13.    unsigned char y1,y2,i,j;
  14.    P2DIR |= BIT2;
  15.    P3DIR |= BIT0;
  16.    DCOCTL  = CALBC1_16MHZ;
  17.    BCSCTL1 = CALBC1_16MHZ;
  18.    WDTCTL = WDTPW + WDTHOLD;
  19.    LCD19264Initial();
  20.    LCD19264Draw_PM(tab);
  21.    ADC_Init();   
  22.    _EINT();
  23.    
  24.    
  25.    while(1)
  26.    {
  27.      
  28. /**********************检测按键S2**************************/
  29.       if(!(P1IN&(0x01<<S2)))
  30.       {
  31.         if(Delay_Time<16384)
  32.         {
  33.          while(!(P1IN&(0x01<<S2)));
  34.          Delay_Time = Delay_Time<<2;
  35.         }
  36.       }
  37.      
  38. /**********************检测按键S3**************************/
  39.       if(!(P1IN&(0x01<<S3)))
  40.       {
  41.         if(Delay_Time>4)
  42.         {
  43.          while(!(P1IN&(0x01<<S3)));
  44.          Delay_Time = Delay_Time>>2;
  45.         }
  46.       }
  47.      
  48. /******************************************************************/
  49. /***************************显示一屏数据***************************/
  50.      
  51.       if(index == Num_of_Results)                 //在主程序中显示一屏数据
  52.       {
  53.          index = 0;
  54.          for(i=1;i<=Num_of_Results-1;i++)
  55.          {
  56.             y1 = y2;
  57.             y2 = 61 - (results[i]/17);
  58.             LCD19264WriteDot(i,y2,1);                      //打点
  59.             
  60.            if((abs(y2 - y1) >=3)&(i!=1) )                  //为了看起来连续,当y轴间距大于等于3,画线
  61.            {
  62.               LCD19264DrawLine_Y(y1,y2,i,1);
  63.            }
  64.            
  65.          }
  66.          
  67. /***************************测量最大值,最小值,Vpp并且显示***************************/
  68.          
  69.       Measure_Vol();                         //测量最大值最小值     
  70.       
  71.       Delay_Nms(500);                        //延时一段时间,使屏幕变化不那么快
  72.       
  73. /**********************检测按键S1**************************/
  74.       while(!(P1IN&(0x01<<S1)));                // FREEZE,锁定屏幕
  75. /**********************检测按键S1**************************/
  76.       
  77. /***************************删除之前显示一屏的数据********************************/
  78.       
  79.       for(i=1;i<=Num_of_Results-1;i++)
  80.          {
  81.             y1 = y2;
  82.             y2 = 61 - (results[i]/17);
  83.             LCD19264WriteDot(i,y2,0);
  84.            if( (abs(y2 - y1) >=3)&(i!=1) )                //因y1初始值为0,有可能比y2小,所以i!=1时画线
  85.            {
  86.               LCD19264DrawLine_Y(y1,y2,i,0);
  87.            }
  88.          }
  89.          
  90. /***************************显示背景界面的点********************************/
  91.       
  92.          for(i=1;i<162;i+=10)
  93.          {
  94.              for(j=1;j<62;j+=15)
  95.              {
  96.                  LCD19264WriteDot(i,j,1);
  97.              }
  98.          }
  99.       
  100. /***************************显示横轴和纵轴********************************/
  101.       
  102.          for(i=0;i<80;i++)
  103.          {
  104.            LCD19264WriteDot((2*i+1),31,1);
  105.            
  106.            if(i<31)
  107.            LCD19264WriteDot(81,(2*i+1),1);
  108.          }
  109.       ADC10CTL0 |= ADC10IE;                               //开ADC中断
  110.       }
  111.       _NOP();
  112.    }
  113. }
复制代码
全部源码下载:

12864 自制版示波器.rar (85.12 KB, 下载次数: 115)
回复

使用道具 举报

ID:79034 发表于 2016-10-12 08:10 | 显示全部楼层
赞一个,可是我不会MSP430.我想用STM32或者51带彩屏做一个。
回复

使用道具 举报

ID:141118 发表于 2016-10-15 13:47 | 显示全部楼层
看看 啥效果
回复

使用道具 举报

ID:168687 发表于 2017-3-6 21:59 | 显示全部楼层
真的不错!!赞一个
回复

使用道具 举报

ID:169871 发表于 2017-3-26 16:11 | 显示全部楼层
真的厉害
回复

使用道具 举报

ID:224571 发表于 2017-8-4 01:14 | 显示全部楼层
学习了
回复

使用道具 举报

ID:91165 发表于 2017-8-4 09:03 | 显示全部楼层
学习了,谢谢楼主分享
回复

使用道具 举报

ID:417443 发表于 2018-10-29 18:34 来自手机 | 显示全部楼层
真的赞
回复

使用道具 举报

ID:418150 发表于 2018-10-30 21:39 | 显示全部楼层
电路原理图可以提供一下吗
回复

使用道具 举报

ID:325030 发表于 2019-10-30 12:26 | 显示全部楼层
厉害的,可以一看
回复

使用道具 举报

ID:126173 发表于 2020-10-9 09:33 | 显示全部楼层
学习了 ,不错,而且 电路 源程序都开源了,可以给大家做为参考。谢谢你
回复

使用道具 举报

ID:236060 发表于 2020-10-9 17:45 | 显示全部楼层
感谢分享,太详细了
回复

使用道具 举报

ID:64696 发表于 2020-10-16 10:22 | 显示全部楼层
谢谢大侠无私奉献学习了、论坛有你更精彩!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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