這是我大三時的課程設計,設計要求如下:
1.時柵傳感器模擬器:通過輸入兩路時間和空間的信號。
(1) 設計一路正弦載波信號模擬信號輸出 sina * cos(wt)
(2) 設計一路余弦信號模擬信號輸出 cosa *sin(wt)
(3) 設計兩路信號的合成模擬信號輸出 sin(wt+a)
2. 設計數據采集模塊。(要求整周期采樣)
3. ARM硬件接口電路設計:顯示路和鍵盤電路
4. 軟件設計:數字相關算法求解角度、顯示、按鍵、A/D.
5. proteus仿真和實做。希望對大家有用!
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (19.79 KB, 下載次數: 117)
下載附件
2018-4-10 17:01 上傳
0.png (48.96 KB, 下載次數: 105)
下載附件
2018-4-10 17:01 上傳
LPC2138單片機源程序如下:
- #include "config.h"
- //#include "LPC21xx.h"
- #include "math.h"
- //#define Fpclk 12000000
- //typedef unsigned char uint8; /* defined for unsigned 8-bits integer variable 無符號8位整型變量 */
- //typedef signed char int8; /* defined for signed 8-bits integer variable 有符號8位整型變量 */
- //typedef unsigned short uint16; /* defined for unsigned 16-bits integer variable 無符號16位整型變量 */
- //typedef signed short int16; /* defined for signed 16-bits integer variable 有符號16位整型變量 */
- //typedef unsigned int uint32; /* defined for unsigned 32-bits integer variable 無符號32位整型變量 */
- //typedef signed int int32; /* defined for signed 32-bits integer variable 有符號32位整型變量 */
- //typedef float fp32; /* single precision floating point variable (32bits) 單精度浮點數(32位長度) */
- //typedef double fp64; /* double precision floating point variable (64bits) 雙精度浮點數(64位長度) */
- #define IO_RS 0x1000000
- #define IO_RW 0x2000000
- #define IO_EN 0x4000000
- #define LED 0X01
- #define KEY1 (IO0PIN&(1<<20))
- #define KEY2 (IO0PIN&(1<<21))
-
- int32 k=0,ADC_Data,tt1,tt2;
- uint32 A=1,FG1=1,FG2=2;
- uint32 a,i,h,j,p,q,m,n,u,v;
- double c,s,data_1=0,data_2=0,data_3=0,data_4=0;
- double x,y,PI=3.141592653589793238462643383279502;
- int32 Buffer[256];
- double SINCE[19]={
- 0.0000,0.0872,0.1736,0.2588,0.3420,0.4226,
- 0.5000,0.5736,0.6428,0.7071,0.7660,0.8192,
- 0.8660,0.9063,0.9397,0.9659,0.9848,0.9962,
- 1.0000,
- };
- double COSCE[19]={
- 1.0000,0.9962,0.9848,0.9659,0.9397,0.9063,
- 0.8660,0.8192,0.7660,0.7071,0.6428,0.5736,
- 0.5000,0.4226,0.3420,0.2588,0.1736,0.0872,
- 0.0000,
- };
-
- const int16 sindata[]={
- 0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,
- 0x98,0x9b,0x9e,0xa1,0xa4,0xa7,0xaa,0xad,
- …………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
- 0xfc,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,
- };
- #define RS_1 IO1SET=(IO_RS&0xFFFFFFFF)
- #define RS_0 IO1CLR=(IO_RS&0xFFFFFFFF)
- #define RW_1 IO1SET=(IO_RW&0xFFFFFFFF)
- #define RW_0 IO1CLR=(IO_RW&0xFFFFFFFF)
- #define EN_1 IO1SET=(IO_EN&0xFFFFFFFF)
- #define EN_0 IO1CLR=(IO_EN&0xFFFFFFFF)
- void delayms(unsigned int t)
- {
- unsigned char u,v;
- for(u=0;u<100;u++)
- for(v=0;v<81;v++);
- }
- void LCD_write_com(unsigned char com) //LCD寫入命令函數
- {
- RS_0;
- RW_0;
- EN_1;
- IO1SET=com<<16;
- delayms(5);
- EN_0;
- IO1CLR=0xFF0000;
- }
- void LCD_write_data(unsigned char data) //寫入數據函數
- {
- RS_1;
- RW_0;
- EN_1;
- IO1SET=data<<16;
- delayms(5);
- EN_0;
- IO1CLR=0xFF0000;
- }
- void LCD_clear() //LCD清屏函數
- {
- LCD_write_com(0x01);
- delayms(5);
- }
- void LCD_write_char(unsigned char x,unsigned char y,unsigned char s) //寫入字符函數
- {
- if (y == 0)
- {
- LCD_write_com(0x80+x);
- }
- else
- {
- LCD_write_com(0xC0+x);
- }
- LCD_write_data(s);
- }
- void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s) //寫入字符串函數
- {
- if (y == 0)
- {
- LCD_write_com(0x80 + x); //表示第一行
- }
- else
- {
- LCD_write_com(0xC0 + x); //表示第二行
- }
- while (*s)
- {
- LCD_write_data( *s);
- s++;
- }
- }
- void LCD_init() //LCD初始化
- {
- LCD_write_com(0x38); //顯示模式設置
- delayms(5);
- LCD_write_com(0x38);
- delayms(5);
- LCD_write_com(0x38);
- delayms(5);
- LCD_write_com(0x38);
- LCD_write_com(0x08); //顯示關閉
- LCD_write_com(0x01); //清屏
- LCD_write_com(0x06); //顯示光標移動設置
- delayms(5);
- LCD_write_com(0x0C); //顯示開及光標設置
-
- }
- /*
- void UART0Init(uint32 bps)
- {
- uint16 Fdiv;
- PINSEL0 = (PINSEL0 & (~0x0F)) | 0x05;
- U0LCR = 0x83;
- Fdiv = (Fpclk / 16) / bps;
- U0DLM = Fdiv / 256;
- U0DLL = Fdiv % 256;
- U0LCR = 0x03;
- }
- */
- void __irq IRQ_Timer0 (void)
- {
- // for(i=0;i<256;i++)
- // {
- // y=COSCE[a];
- // x=SINCE[a];
- // s=(y*sindata[i]);
- // c=(x*cosdata[i]);
- //
- // sindata[i]=sin(2.0*acos(-1.0)/256*i);
- // cosdata[i]=cos(2.0*acos(-1.0)/256*i);
- //
- // h=(s*0x1ff+0x1ff);
- // h=s+c;
- // DACR=((sindata[i]<<6))|(1<<16);
- // for(j=0;j<0x20;j++);
-
- if((IO0PIN&KEY1)==0)
- {
- if(FG1!=(A-5))
- {
- FG1=A;A+=5;i=0;
- if(A>360) A=0;
- }
- }
-
- if((IO0PIN&KEY1)!=0){ FG1=1; }
- a=A*180/PI;
- if((IO0PIN&KEY2)==0)
- {
- if(FG2!=(A+5))
- {FG2=A;A-=5;i=0;
- if(A>360)A=0;}
- }
- if((IO0PIN&KEY2)!=0){ FG2=1; }
- if(A<=90) a=A/5;
- if(A>90&A<=180) a=36-A/5;
- if(A>180&A<270) a=A/5-36;
- if(A>=270&A<360) a=72-A/5;
-
- y=COSCE[a];
- x=SINCE[a];
- s=(y*sindata[i]);
- c=(x*cosdata[i]);
-
- // sindata[i]=sin(2.0*acos(-1.0)/256*i);
- // cosdata[i]=cos(2.0*acos(-1.0)/256*i);
-
- // h=(s*0x1ff+0x1ff);
- h=s+c;
- DACR=((h<<6))|(1<<16);
- for(j=0;j<0x20;j++);
-
-
- AD0CR = (AD0CR&0x00FFFF00)|0x01|(1 << 24); // 設置AD0.0,并進行第一次轉換
- while( (AD0DR&0x80000000)==0 ); // 等待轉換結束
- ADC_Data = AD0DR; // 讀取ADC結果
- ADC_Data = (ADC_Data>>6) & 0x3FF; // 提取AD轉換值
-
- Buffer[i]=ADC_Data;
-
- LCD_write_char(9,0,A/100%10+0X30);
- LCD_write_char(10,0,A/10%10+0X30);
- LCD_write_char(11,0,A%10+0X30);
- for(u=0;u<256;u++)
- {
- data_1 = data_1 +(Buffer[u]-0x7f)*(cosdata[u]-0x7f)/256;//-5170)*PI/128;
- data_2 = data_2 +(Buffer[u]-0x7f)*(sindata[u]-0x7f)/256;//-5170)*PI/128;
- }
- data_4 = atan(data_1 /data_2)*180/acos(-1.0);
- tt1=data_4*10;//1;
-
- if(A>90&A<180) tt1=1800-tt1;
- if(A>180&A<270) tt1=1800+tt1;
- if(A>270&A<360) tt1=3600-tt1;
-
- LCD_write_char(9,1,tt1/1000%10+0X30);
- LCD_write_char(10,1,tt1/100%10+0X30);
- LCD_write_char(11,1,tt1/10%10+0X30);
- LCD_write_char(12,1,'.');
- LCD_write_char(13,1,tt1%10+0X30);
-
- // LCD_write_char(6,1,tt2/1000%10+0X30);
- // LCD_write_char(7,1,tt2/100%10+0X30);
- // LCD_write_char(8,1,tt2/10%10+0X30);
- // LCD_write_char(9,1,'.');
- // LCD_write_char(10,1,tt2%10+0X30);
- i++;
- if(i>=256) i=0;
- T0IR = 0x02; /* 清除中斷標志 */
- VICVectAddr = 0x00; /* 通知VIC中斷處理結束 */
- //}
- }
- void Time0Init(void)
- {
- T0TC = 0; // 定時器T0初始化
- T0PR = 10; // 設置定時器0分頻為100分頻,得120000Hz
- T0MCR = 0x03<<3; // 匹配通道MR1匹配中斷并復位TC
- T0MR0 = Fpclk/12000; // MR0比較值(0.5秒定時值)
- T0MR1 = Fpclk/1200; // MR1比較值(0.5秒定時值)
- T0EMR = 0x30; // 設置定時器0的MR0匹配輸出,輸出方式為翻轉
- T0TCR = 0x03; // 啟動并復位T0TC
- T0TCR = 0x01;
- T0IR = 0x02;
- /* 設置定時器0中斷IRQ */
- VICIntSelect = 0x00; // 所有中斷通道設置為IRQ中斷
- VICVectCntl0 = 0x20 | 0x04; // 分配定時器0中斷到通道0(最高優先級)
- VICVectAddr0 = (uint32)IRQ_Timer0; // 設置中斷服務程序地址向量
- VICIntEnable = (1<<4); // 使能定時器0中斷
- // IRQEnable(); // 使能IRQ中斷
- }
- int main(void)
- {
- PINSEL0|=0x00000000;
- PINSEL1 |= 0x01400000;
- PINSEL1 = (PINSEL1&(~(0x03<<18))) | (0x02<<18); // P0.25 連接Aout
- // UART0Init(9600);
- IO0DIR|=0X01;
- IO1DIR|=0x07ff0000;
- LCD_init();
- Time0Init();
- AD0CR = (1 << 0) |
- ((Fpclk / 1000000 - 1) << 8) |
- (0 << 16) |
- (0 << 17) |
- (1 << 21) |
- (0 << 22) |
- (1 << 24) |
- (0 << 27);
- delayms(10);
- ADC_Data = AD0DR;
-
- LCD_write_string(0,0,"in:");
- LCD_write_string(0,1,"out:");
-
- while(1)
- {
- // y=COSCE[a];
- // x=SINCE[a];
- // s=(y*sindata[i]);
- // c=(x*cosdata[i]);
-
- // sindata[i]=sin(2.0*acos(-1.0)/256*i);
- // cosdata[i]=cos(2.0*acos(-1.0)/256*i);
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
數字信號處理課程設計.zip
(343.14 KB, 下載次數: 77)
2018-4-10 11:23 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|