单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:4679|回复:2

基于数字相关的时栅信号处理设计LPC2138源程序及proteus仿真

[复制链接]
ID:304995发表于 2018-4-10 11:24|显示全部楼层
这是我大三时的课程设计,设计要求如下:

1.时栅传感器模拟器:通过输入两路时间和空间的信号。

(1) 设计一路正弦载波信号模拟信号输出 sina * cos(wt)

(2) 设计一路余弦信号模拟信号输出     cosa *sin(wt)
   (3) 设计两路信号的合成模拟信号输出   sin(wt+a)
2. 设计数据采集模块。(要求整周期采样)

3.  ARM硬件接口电路设计:显示路和键盘电路

4. 软件设计:数字相关算法求解角度、显示、按键、A/D.
5.  proteus仿真和实做。希望对大家有用!

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
0.png
LPC2138单片机源程序如下:
  1. #include  "config.h"
  2. //#include  "LPC21xx.h"
  3. #include "math.h"

  4. //#define Fpclk 12000000
  5. //typedef unsigned char  uint8;             /* defined for unsigned 8-bits integer variable       无符号8位整型变量  */
  6. //typedef signed   char  int8;               /* defined for signed 8-bits integer variable           有符号8位整型变量  */
  7. //typedef unsigned short uint16;             /* defined for unsigned 16-bits integer variable       无符号16位整型变量 */
  8. //typedef signed   short int16;             /* defined for signed 16-bits integer variable             有符号16位整型变量 */
  9. //typedef unsigned int   uint32;             /* defined for unsigned 32-bits integer variable       无符号32位整型变量 */
  10. //typedef signed   int   int32;             /* defined for signed 32-bits integer variable             有符号32位整型变量 */
  11. //typedef float       fp32;               /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
  12. //typedef double       fp64;               /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
  13. #define IO_RS   0x1000000
  14. #define IO_RW   0x2000000
  15. #define IO_EN   0x4000000
  16. #define LED 0X01
  17. #define KEY1 (IO0PIN&(1<<20))
  18. #define KEY2 (IO0PIN&(1<<21))  
  19.     
  20. int32  k=0,ADC_Data,tt1,tt2;
  21. uint32 A=1,FG1=1,FG2=2;
  22. uint32 a,i,h,j,p,q,m,n,u,v;
  23. double c,s,data_1=0,data_2=0,data_3=0,data_4=0;
  24. double x,y,PI=3.141592653589793238462643383279502;
  25. int32 Buffer[256];

  26. double SINCE[19]={
  27. 0.0000,0.0872,0.1736,0.2588,0.3420,0.4226,
  28. 0.5000,0.5736,0.6428,0.7071,0.7660,0.8192,
  29. 0.8660,0.9063,0.9397,0.9659,0.9848,0.9962,
  30. 1.0000,
  31. };

  32. double COSCE[19]={
  33. 1.0000,0.9962,0.9848,0.9659,0.9397,0.9063,
  34. 0.8660,0.8192,0.7660,0.7071,0.6428,0.5736,
  35. 0.5000,0.4226,0.3420,0.2588,0.1736,0.0872,
  36. 0.0000,
  37. };
  38.       
  39. const int16 sindata[]={
  40. 0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,
  41. 0x98,0x9b,0x9e,0xa1,0xa4,0xa7,0xaa,0xad,
  42. …………
  43. …………限于本文篇幅 余下代码请从51黑下载附件…………

  44. 0xfc,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,
  45. };

  46. #define RS_1   IO1SET=(IO_RS&0xFFFFFFFF)
  47. #define RS_0   IO1CLR=(IO_RS&0xFFFFFFFF)
  48. #define RW_1   IO1SET=(IO_RW&0xFFFFFFFF)
  49. #define RW_0   IO1CLR=(IO_RW&0xFFFFFFFF)
  50. #define EN_1   IO1SET=(IO_EN&0xFFFFFFFF)
  51. #define EN_0   IO1CLR=(IO_EN&0xFFFFFFFF)


  52. void delayms(unsigned int t)
  53. {
  54.        unsigned char u,v;
  55.        for(u=0;u<100;u++)
  56.        for(v=0;v<81;v++);
  57. }

  58. void LCD_write_com(unsigned char com)           //LCD写入命令函数
  59. {
  60.        RS_0;
  61.        RW_0;
  62.        EN_1;
  63.        IO1SET=com<<16;
  64.        delayms(5);
  65.        EN_0;
  66.        IO1CLR=0xFF0000;
  67. }

  68. void LCD_write_data(unsigned char data)         //写入数据函数
  69. {
  70.        RS_1;
  71.   RW_0;
  72.   EN_1;
  73.   IO1SET=data<<16;
  74.        delayms(5);      
  75.   EN_0;
  76.        IO1CLR=0xFF0000;
  77. }

  78. void LCD_clear()                       //LCD清屏函数
  79. {
  80.        LCD_write_com(0x01);
  81.        delayms(5);
  82. }

  83. void LCD_write_char(unsigned char x,unsigned char y,unsigned char s)   //写入字符函数
  84. {    
  85. if (y == 0)
  86.        {    
  87.        LCD_write_com(0x80+x);    
  88.        }  
  89. else
  90.        {    
  91.        LCD_write_com(0xC0+x);    
  92.        }      
  93. LCD_write_data(s);  
  94. }

  95. void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s)   //写入字符串函数
  96. {    
  97. if (y == 0)
  98.        {    
  99.        LCD_write_com(0x80 + x);     //表示第一行
  100.        }
  101. else
  102.        {    
  103.        LCD_write_com(0xC0 + x);     //表示第二行
  104.        }      
  105. while (*s)
  106.        {    
  107.    LCD_write_data( *s);    
  108.    s++;    
  109.        }
  110. }

  111. void LCD_init()     //LCD初始化
  112. {
  113.        LCD_write_com(0x38);       //显示模式设置
  114.        delayms(5);
  115.        LCD_write_com(0x38);
  116.        delayms(5);
  117.        LCD_write_com(0x38);
  118.        delayms(5);
  119.        LCD_write_com(0x38);      
  120.        LCD_write_com(0x08);           //显示关闭
  121.        LCD_write_com(0x01);       //清屏
  122.        LCD_write_com(0x06);       //显示光标移动设置
  123.        delayms(5);
  124.        LCD_write_com(0x0C);       //显示开及光标设置
  125.   
  126. }
  127. /*
  128. void  UART0Init(uint32 bps)
  129. {  
  130.    uint16 Fdiv;
  131.    PINSEL0 = (PINSEL0& (~0x0F)) | 0x05;      
  132.    U0LCR = 0x83;                                      
  133.    Fdiv = (Fpclk / 16) / bps;                
  134.    U0DLM = Fdiv / 256;                                      
  135.    U0DLL = Fdiv % 256;                                
  136.    U0LCR = 0x03;
  137. }
  138. */
  139.    void __irq IRQ_Timer0 (void)
  140. {  
  141. //         for(i=0;i<256;i++)
  142. //         {      
  143. //                       y=COSCE[a];
  144. //                       x=SINCE[a];
  145. //                       s=(y*sindata[i]);
  146. //                       c=(x*cosdata[i]);
  147. //                      
  148. //                       sindata[i]=sin(2.0*acos(-1.0)/256*i);
  149. //                       cosdata[i]=cos(2.0*acos(-1.0)/256*i);
  150. //                      
  151. //                       h=(s*0x1ff+0x1ff);
  152. //                       h=s+c;
  153. //                       DACR=((sindata[i]<<6))|(1<<16);
  154. //                       for(j=0;j<0x20;j++);
  155.       
  156.                  if((IO0PIN&KEY1)==0)
  157.      {
  158.                    if(FG1!=(A-5))
  159.                    {
  160.                      FG1=A;A+=5;i=0;
  161.                              if(A>360) A=0;
  162.                    }
  163.                  }
  164.                 
  165.      if((IO0PIN&KEY1)!=0){ FG1=1; }
  166.                    a=A*180/PI;
  167.              if((IO0PIN&KEY2)==0)
  168.      {
  169.                      if(FG2!=(A+5))
  170.                  {FG2=A;A-=5;i=0;
  171.                  if(A>360)A=0;}
  172.                  }
  173.                  if((IO0PIN&KEY2)!=0){ FG2=1; }
  174.                  if(A<=90)   a=A/5;
  175.                  if(A>90&A<=180)  a=36-A/5;
  176.                  if(A>180&A<270)  a=A/5-36;
  177.                  if(A>=270&A<360) a=72-A/5;
  178.                 
  179.                  y=COSCE[a];
  180.              x=SINCE[a];
  181.                  s=(y*sindata[i]);
  182.                  c=(x*cosdata[i]);
  183.                 
  184. //                 sindata[i]=sin(2.0*acos(-1.0)/256*i);
  185. //                 cosdata[i]=cos(2.0*acos(-1.0)/256*i);
  186.                 
  187. //                 h=(s*0x1ff+0x1ff);
  188.                  h=s+c;
  189.                  DACR=((h<<6))|(1<<16);
  190.                  for(j=0;j<0x20;j++);
  191.     
  192.           
  193.                  AD0CR = (AD0CR&0x00FFFF00)|0x01|(1<< 24);       // 设置AD0.0,并进行第一次转换
  194.                  while( (AD0DR&0x80000000)==0 );               // 等待转换结束
  195.                  ADC_Data = AD0DR;                                       // 读取ADC结果
  196.                  ADC_Data = (ADC_Data>>6)& 0x3FF;         // 提取AD转换值

  197.                 
  198.                  Buffer[i]=ADC_Data;
  199.         
  200.          LCD_write_char(9,0,A/100%10+0X30);
  201.          LCD_write_char(10,0,A/10%10+0X30);
  202.          LCD_write_char(11,0,A%10+0X30);

  203.            for(u=0;u<256;u++)
  204.            {
  205.                  data_1 = data_1 +(Buffer[u]-0x7f)*(cosdata[u]-0x7f)/256;//-5170)*PI/128;
  206.                  data_2 = data_2 +(Buffer[u]-0x7f)*(sindata[u]-0x7f)/256;//-5170)*PI/128;      
  207.            }
  208.                  data_4 = atan(data_1 /data_2)*180/acos(-1.0);
  209.                  tt1=data_4*10;//1;
  210.                 
  211.                  if(A>90&A<180)   tt1=1800-tt1;
  212.                  if(A>180&A<270)  tt1=1800+tt1;  
  213.                  if(A>270&A<360)  tt1=3600-tt1;  
  214.           
  215.                  LCD_write_char(9,1,tt1/1000%10+0X30);      
  216.                  LCD_write_char(10,1,tt1/100%10+0X30);
  217.                  LCD_write_char(11,1,tt1/10%10+0X30);
  218.                  LCD_write_char(12,1,'.');
  219.                  LCD_write_char(13,1,tt1%10+0X30);
  220.         

  221. //       LCD_write_char(6,1,tt2/1000%10+0X30);      
  222. //       LCD_write_char(7,1,tt2/100%10+0X30);
  223. //   LCD_write_char(8,1,tt2/10%10+0X30);
  224. //   LCD_write_char(9,1,'.');
  225. //       LCD_write_char(10,1,tt2%10+0X30);
  226.    i++;
  227.    if(i>=256) i=0;
  228.        T0IR = 0x02;                       /* 清除中断标志                                                 */
  229.        VICVectAddr = 0x00;                 /* 通知VIC中断处理结束                                       */
  230. //}
  231. }

  232. void  Time0Init(void)
  233. {  
  234.          T0TC   = 0;                     // 定时器T0初始化
  235.          T0PR = 10;           // 设置定时器0分频为100分频,得120000Hz
  236.    T0MCR = 0x03<<3;           // 匹配通道MR1匹配中断并复位TC
  237.        T0MR0 = Fpclk/12000;       // MR0比较值(0.5秒定时值)
  238.        T0MR1 = Fpclk/1200;       // MR1比较值(0.5秒定时值)
  239.    T0EMR = 0x30;               // 设置定时器0的MR0匹配输出,输出方式为翻转
  240.        T0TCR = 0x03;         // 启动并复位T0TC
  241.        T0TCR = 0x01;    
  242.    T0IR = 0x02;

  243.    /* 设置定时器0中断IRQ */
  244.    VICIntSelect = 0x00;                           // 所有中断通道设置为IRQ中断
  245.    VICVectCntl0 = 0x20 | 0x04;                 // 分配定时器0中断到通道0(最高优先级)
  246.    VICVectAddr0 = (uint32)IRQ_Timer0;       // 设置中断服务程序地址向量
  247.    VICIntEnable = (1<<4);               // 使能定时器0中断
  248. //   IRQEnable();                                 // 使能IRQ中断
  249. }

  250. int  main(void)
  251. {        
  252.    PINSEL0|=0x00000000;          
  253.          PINSEL1 |= 0x01400000;
  254.        PINSEL1 = (PINSEL1&(~(0x03<<18))) | (0x02<<18); // P0.25 连接Aout
  255. //   UART0Init(9600);
  256.    IO0DIR|=0X01;                                
  257.        IO1DIR|=0x07ff0000;
  258.          LCD_init();                                          
  259.        Time0Init();
  260.    AD0CR = (1<< 0)               |      
  261.          ((Fpclk / 1000000 - 1)<< 8) |      
  262.          (0<< 16)               |      
  263.          (0<< 17)               |      
  264.          (1<< 21)               |            
  265.          (0<< 22)               |            
  266.          (1<< 24)               |            
  267.          (0<< 27);                                      
  268.    delayms(10);                                          
  269.    ADC_Data = AD0DR;

  270.        LCD_write_string(0,0,"in:");
  271.        LCD_write_string(0,1,"out:");          
  272.       
  273.    while(1)
  274.    {
  275. //             y=COSCE[a];
  276. //                       x=SINCE[a];
  277. //                       s=(y*sindata[i]);
  278. //                       c=(x*cosdata[i]);
  279.                       
  280. //                       sindata[i]=sin(2.0*acos(-1.0)/256*i);
  281. //                       cosdata[i]=cos(2.0*acos(-1.0)/256*i);
  282.                       
  283. ……………………

  284. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
数字信号处理课程设计.zip(343.14 KB, 下载次数: 77)

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

ID:858959发表于 2021-3-27 20:50来自手机|显示全部楼层
有错误,不能直接使用
ID:858959发表于 2021-3-27 20:50来自手机|显示全部楼层
需要修改,不知道是电路问题还是代码问题

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

Powered by 单片机教程网