单片机控制12864产生正弦波的程序(原创)
- 格式:doc
- 大小:57.50 KB
- 文档页数:14
用单片机产生正弦波程序Document serial number [UU89WT-UU98YT-UU8CB-UUUT-UUT108] 用单片机产生正弦波程序要用到数模转换DAC0832MOV DPTR, #SINTAB ;正弦表写入内部RAM6DH-7FH MOV R0,#6DHLOOP: CLR AMOVC A, @A+DPTRMOV @R0, AINC DPTRINC ROCJNE RO,#80H, LOOPMOV DPTR, #7FFFH ;设置D/A转换器的端口地址MOV R0,#6DH ;设置正弦表指针LOOP1: MOV A, @R0 ;查表MOVX @DPTR, A ; D/A 转换ACALL DELAY ;延时,等待转换结束DEC RO ;正弦表位移量增量CJNE RO, #6DH, LOOP1 ;第一象限输出完LOOP2: MOV A, @R0 ;査表MOVX @DPTR, A ; D/A 转换acall DELAY ;延时,等待转换结束DEC RO ;正弦表位移量减量CJNE RO, #6DH, L00P2 ;第二象限输出完LOOP3: MOV A, @R0 ;查表CPL A ;表值取反MOVX @DPTR, A ;D/A 转换ACALL DELAY ;延时,等待转换结束INC RO ;正弦表位移量增量CJNE RO, #7FH, LOOP3 ;第三象限输出完L00P4: MOV A, @R0 ;查表CPL A ;表值取反MOVX @DPTR, A ;D/A 转换ACALL DELAY ;延时,等待转换结束DEC RO ;正弦表位移量减量CJNE RO, #6DH, L00P4 ;第四象限输出完SJMP LOOP1DELAY:MOV R7, #200 ;延时50msDELI:MOV R6,#123NOPDEL2: JNZ R6, DEL2DJNZ R7, DELIRET SINTAB:DB 80H, 83H, 86H, 89H, SDH, 90H, 93H, 96HDB 99H, 9CH, 9FH, 0A2H, 0A5H, 0A8H, OABH, OAEH DB OB1H, 0B4H, OB7H, OBAH, OBCH, OBFH, 0C2H,0C5HDB OC7H, OCAH, OCCH, OCFH,OD1H, 0D4H, 0D6H, 0D8H DB ODAH, ODDH, ODFH, OE1H, 0E3H, 0E5H, OE7H, 0E9H DB OEAH, OECH, OEEH, OEFH, OF1H, 0F2H, 0F4H, 0F5H DB 0F6H, 0F7H, 0F8H, 0F9H, OFAH,OFBH,OFCH, OFDH DB OFDH, OFEH, OFFH, OFFH, OFFH, OFFH, OFFH, OFFH DB OFFH, OFFH, OFFH, OFFH,OFFH, OFFH, OFEH, OFDH DB OFDH, OFCH, OFBH, OFAH, 0F9H, 0F8H, OF7H, 0F6H DB OF5H, 0F4H, 0F2H, OF1H, OEFH, OEEH, OECH, OEAHDB 0E9H, 0E7H, 0E5H, 0E3H, OE1H, ODEH, ODDH, ODAHDB 0D8H, 0D6H, 0D4H, OD1H, OCFH, OCCH,OCAH, 0C7HDB 0C5H, 0C2H, OBFH, OBCH, OBAH, OB7H, 0B4H, OB1H DB 96H, 93H, 90H, SDH, 89H, 86H, 83H, 80H DB 80H, 7CH, 79H, 78H, 72H, 6FH, 6CH, 69H DB 66H, 63H, 60H, 5DH, 5 AH, 57H, 55H, 51H DB 4EH, 4CH, 48H, 45H, 43H, 40H, 3DH, 3 AH DB 38H, 35H, 33H, 30H, 2EH, 2BH, 29H, 27H DB 25H, 22H, 20H, 1EH, 1CH, 1AH, 18H, 16H OAEH, OABH, 0A8H, 0A5H,0A2H, DB 9FH, 9CH, DB 15H, 13H, 11H, 1OH, OEH, ODH, OBH, OAH99HDB 09H, OSH, O7H, 06H, 05H, 04H, 03H, 02HDB 02H, O1H, OOH, OOH, OOH, OOH, OOH, OOH DB OOH, OOH, OOH, OOH, OOH, OOH, O1H, 02H DB 02H, 03H, 04H, 05H, 06H, O7H, OSH, 09H DB OAH, OBH, ODH, OEH, 1OH, 11H, 13H, 15H DB 16H, 18H, 1AH, 1CH, 1EH, 2OH, 22H, 25H DB 27H, 29H, 2BH, 2EH, 30H, 33H, 35H, 38H DB 3 AH, 3DH, 40H, 43H, 45H, 48H, 4CH, 4EH DB 51H, 55H, 57H, 5 AH, SDH, 60H, 63H, 66HDB 69H, 6CH, 6FH, 72H, 76H, 79H, 7CH, 80H END。
#include <reg51.h>#include <intrins.h>#include <ADC0808.c>sbit DI=P2^2; // 数据\指令选择sbit RW=P2^1; // 读\写选择sbit E=P2^0; // 读\写使能sbit CS1=P2^4; // 片选1sbit CS2=P2^3; // 片选2sbit busy=P1^7;sbit jia=P3^7;sbit jian=P3^3;sbit jia1=P3^0;sbit jian1=P3^1;unsigned int i;unsigned char ye,lei,shu; unsigned char a[94];char code t[]={0x00,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x40,0x60,0x80,0x00,0x7F,0xFF, //小0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x80,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x82,0x00,0x82,0x00,0x82,0x40,0x82,0x80,0x82,0x7F,0xE2, //子0x00,0xA2,0x00,0x92,0x00,0x8A,0x00,0x86,0x00,0x80,0x00,0xC0,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x60,0x3F,0x5E,0x01,0x48,0x01,0x48,0xFF,0xFF,0x11,0x48,0x21,0x4C, //制0x1F,0x68,0x00,0x40,0x07,0xF8,0x40,0x00,0x80,0x00,0x7F,0xFF,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x00,0x20,0xFF,0xF8,0x00,0x87,0x00,0x40,0x00,0x30,0x00,0x0F, //作0xFF,0xF8,0x08,0x88,0x08,0x88,0x08,0xC8,0x0C,0x88,0x08,0x0C,0x00,0x08,0x00,0x00,};void checkstate(){//bit dat;DI=0;RW=1;//P1=0x00;do{E=1;E=0;//仅当第7位为0时才可操作(判别busy信号)}while(busy==1);}void writecommand(unsigned char command) //写命令{checkstate();DI=0;RW=0;P1=command;E=1;E=0;}void writedate(unsigned char date) //写数据{checkstate();DI=1;RW=0;P1=date;E=1;E=0;}void pianxuan(unsigned int i){if(i==1)CS1=0,CS2=1;if(i==2)CS1=1,CS2=0;if(i==3)CS1=0,CS2=0;}void cleanscreen() //清屏{unsigned char page,i;for(page=0xb8;page<0xc0;page++){writecommand(page);writecommand(0x40);for(i=0;i<64;i++)writedate(0x00);}}void init(void) //开显示,起始行0行{writecommand(0xc0);writecommand(0x3f);}void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}void shuju(){pianxuan(i); writecommand(ye); writecommand(lei); writedate(shu);}void qing(){uchar i;for(i=0xb8;i<=0xbf;i++) {ye=i;shu=0x00;shuju();}}void main(){uint r,j,g=0,q,dianya=1,k,p;uchar U,m,l;pianxuan(3);cleanscreen();init();pianxuan(2);l=0xb8;for(k=0;k<4;k++,l=l+0x02){ye=l;lei=0x70;for(r=0;r<16;r++){shu=t[2*r+1+32*k];shuju();lei++;}ye=l+0x01;lei=0x70;for(r=0;r<16;r++){shu=t[2*r+32*k];shuju();lei++;}}while(1){uchar d1,d2,d3,d4,d5;aaa:do{adc();}while((AD!=128)&&(AD!=129)&&(AD!=130));U=AD;adc();if(U>AD)goto aaa;while(jia==0){while(jia==0);g=g+1;}while(jian==0){while(jian==0);if(g!=0) g=g-1;}while(jia1==0){while(jia1==0);dianya=dianya+1;}while(jian1==0){while(jian1==0);if(dianya!=1) dianya=dianya-1;}for(j=0;j<94;j++) //AD采样{adc();a[j]=AD;delay_50us(g);}lei=0x40;for(r=0,j=0;r<94;r++,j++){if(j<64) i=1;if(j==64) lei=0x40;if(j>=64)i=2;qing(); //清掉之前的内容AD=a[j]*0.196/dianya; //计算在12864的电压值if(AD<=7) ye=0xbf,shu=(0x80>>AD); else if(AD<=15) ye=0xbe,shu=0x80>>(AD-8); else if(AD<=23) ye=0xbd,shu=0x80>>(AD-16); else if(AD<=31) ye=0xbc,shu=0x80>>(AD-24); else if(AD<=39) ye=0xbb,shu=0x80>>(AD-32); else if(AD<=47) ye=0xba,shu=0x80>>(AD-40); else if(AD<=55) ye=0xb9,shu=0x80>>(AD-48); else if(AD<=63) ye=0xb8,shu=0x80>>(AD-56);if(r==0){d1=shu;d2=ye;}if(r!=0){d3=shu;d4=ye;if(ye==d2){if(shu>d1){d5=shu;d5=d5>>1;while(d5!=d1){d5=d5>>1;shu=shu|(shu>>1);}}if(shu<d1){d5=shu;d5=d5<<1;while(d5!=d1){d5=d5<<1;shu=shu|(shu<<1);}}if(ye<d2){for(q=0;q<7;q++){shu=shu|(shu<<1);}shuju();ye++;while(ye<d2) {shu=0xff,shuju(),ye++;}if(ye==d2){shu=0x01;if(shu<d1){d5=shu;d5=d5<<1;while(d5!=d1){d5=d5<<1;shu=shu|(shu<<1);}}}}if(ye>d2){for(q=0;q<7;q++){shu=shu|(shu>>1);}shuju();ye--;while(ye>d2) {shu=0xff,shuju(),ye--;}if(ye==d2){shu=0x80;if(shu>d1){d5=shu;d5=d5>>1;while(d5!=d1){d5=d5>>1;shu=shu|(shu>>1);}}}}}if(r!=0)d1=d3;d2=d4;}shuju();if(lei!=0x7f) lei++; }}}。
基于单片机片内dac数模转换器的产生正弦波信号的应用编程在基于单片机的应用中,使用片内DAC(数模转换器)产生正弦波信号是一个常见的需求。
下面是一个基本的步骤和代码示例,展示了如何使用单片机和DAC来生成正弦波信号。
步骤概览1. 配置单片机:初始化单片机,配置DAC和其他必要的硬件。
2. 计算正弦波数据:根据所需的频率和幅度,计算正弦波的样本值。
3. 发送数据到DAC:将计算出的样本值发送到DAC以生成正弦波。
示例代码(伪代码)```cinclude <>include <>define SAMPLE_RATE 44100 // 采样率,可以根据需要调整define FREQUENCY 440 // 频率,单位Hzdefine PI // 圆周率define MAX_AMPLITUDE 1023 // DAC的最大幅度,根据DAC规格调整// 初始化DAC和其他硬件void init_hardware() {// ...}// 计算正弦波样本值int calculate_sine_wave(int sample_number) {double angle = 2 PI sample_number / SAMPLE_RATE;return (int)(MAX_AMPLITUDE sin(angle)); // 返回-MAX_AMPLITUDE 到 MAX_AMPLITUDE 的值}// 主函数int main() {init_hardware(); // 初始化硬件for (int sample_number = 0; sample_number < SAMPLE_RATE; sample_number++) {int sine_wave_sample = calculate_sine_wave(sample_number); // 计算正弦波样本值// 将sine_wave_sample发送到DAC以生成正弦波// ...}return 0;}```注意事项硬件配置:具体配置单片机和DAC的代码取决于你所使用的硬件平台和开发环境。
//****************************************************************************// **用51实现LCD12864显示正弦波**周期和幅值都是可调的//****************************************************************************//#include <reg52.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit rs=P1^2;sbit rw=P1^1;sbit e=P1^0;sbit key1=P1^6;sbit key2=P1^7;void delay_50us(uint x){uchar i,j;for(i=0;i<x;i++)for(j=0;j<10;j++);}void du_mang(void) //忙信号检测{rs=0;rw=1;e=1;P0=0xff;while((P0&0x80)==0x80);e=0;}void send_com(uchar com_data) //写指令{du_mang();rs=0;rw=0;e=1;P0=com_data;delay_50us(5);e=0;delay_50us(5);}void send_data(uchar tab_data) //写数据{//du_mang();rs=1;rw=0;e=1;P0=tab_data;delay_50us(5);e=0;delay_50us(5);}void init(void) //初始化函数{delay_50us(10);send_com(0x30);// delay_50us(1);send_com(0x30);// delay_50us(1);send_com(0x0c);// delay_50us(1);send_com(0x01);// delay_50us(1);send_com(0x06);delay_50us(1);}void clrgdram(void) //清除GDRAM {uchar x,y;for(y=0;y<64;y++) //64行for(x=0;x<16;x++) //16列{send_com(0x34);send_com(y+0x80); //行地址send_com(x+0x80); //列地址send_com(0x30);send_data(0x00);send_data(0x00);}}uchar readbyte(void)uchar byreturnvalie;du_mang();P0=0xff;rs=1;rw=1;e=0;e=1;byreturnvalie=P0;e=0;return byreturnvalie;}void huadian(uchar x,uchar y,uchar color) //画点函数{uchar row,tier,tier_bit;uchar readH,readL;send_com(0x34);send_com(0x36);tier=x>>4;tier_bit=x&0x0f;if(y<32){row=y;}else{row=y-32;tier+=8;}send_com(row+0x80);send_com(tier+0x80);readbyte();readH=readbyte();readL=readbyte();send_com(row+0x80);send_com(tier+0x80);if(tier_bit<8){switch(color){case 0: readH&=(~(0x01<<(7-tier_bit)));break;case 1: readH|=(0x01<<(7-tier_bit));break;case 2: readH^=(0x01<<(7-tier_bit));break;default:break;}send_data(readH);send_data(readL);}else{switch(color){case 0: readL&=(~(0x01<<(15-tier_bit)));break;case 1: readL|=(0x01<<(15-tier_bit));break;case 2: readL^=(0x01<<(15-tier_bit));break;default:break;}send_data(readH);send_data(readL);}send_com(0x30);}void main(void){uchar i,j,colour=1;uchar m=10,n=30;init();clrgdram();send_com(0x01);delay_50us(10);while(1){for(i=4;i<124;i++){if(key1==0){m+=5; //改变幅值while(!key1);clrgdram();}if(key2==0){n+=5; //改变周期while(!key2);clrgdram();}j=35-m*sin((i-4)*3.14/n);huadian(i,j,colour);}}}。
51单⽚机⽰波器制作(12864显⽰带字库)⾸先说明:我才接触51单⽚机3个星期(6⽉8号才⾼考完),对C语⾔还很陌⽣。
我就是⼀个萌新,还希望⼤佬们多多指导。
12864(带字库st7920驱动)为显⽰器,XPT2046为AD转换芯⽚。
(不要问我为什么⽤这个芯⽚,开发板⾃带的坑货。
我在⽹上下载的⽰波器程序⼤多以ADC0832或ADC0808为AD转换芯⽚,结果我都⽤不了,所以才被迫⾃写程序。
)⽰波器程序由main.c XPT2046.c XPT2046.h三个⼦⽂件构成,main.c是我根据⽹上的⼀个12864画图程序改编⽽成我也加了⼀些注释,后⾯两个⽂件取⾃开发板⾃带的例程并进⾏了修改。
所以说这个程序基本上不是我编写的,也有很多问题和不⾜之处还请指正。
下⾯是效果图。
⾸先是⽅波。
由于没有函数发⽣器,就只能通过⼿机播放只做好的正弦⾳频,再检测⼿机⽿机接⼝信号。
不知道为什么,正弦波有⼀半不见了,似乎是由于不能检测到负电压还是什么的。
下⾯贴出main.c 的代码。
01.#include <reg52.h>02.#include"XPT2046.h" 03.#define uint unsigned int 04.#define uchar unsigned char05.06.sbit RS=P2^6; //LCD 数据或命令选择端07.sbit RW=P2^5; //LCD 写⼊或读出选择端08.sbit RST=P1^0; //LCD 复位端⼝09.sbit LCDE=P2^7; // LCD 使能端10.sbit PSB=P3^2;//串⾏或并⾏选择端11.12. void delay(uchar i)13. {14. while(i--);15. } //延时函数,i=1时延时约10微秒(12M晶振)16.17. void SPI_Start()18. {19. CLK = 0;20. CS = 1;21. DIN = 1;22. CLK = 1;23. CS = 0;24. } //ADC芯⽚(XPT2046)初始化函数25.26. void lcd_busy()27.28. {29.30. RS=0;31.32. RW=1;33.34. P0=0XFF;35.36. LCDE=1;37.38. delay(14);39.40. while((P0&0x80)==0x80);41. LCDE=0;42.43. }//LCD12864(st7920驱动)查忙函数44.45. void write_com(uchar com)46.47. {48.49. lcd_busy();RS=0;50.51. RW=0;52.53. LCDE=0;54.55. P0=com;56.57. delay(9);58.59. LCDE=1;60.61. delay(9);62.63. LCDE=0;64.65. }//LCD写指令函数66.67. void write_num(uchar num)68.69. {70.71. lcd_busy();72.73. RS=1;75. RW=0;76.77. LCDE=0;78.79. P0=num;80.81. delay(7);82.83. LCDE=1;84.85. delay(9);86.87. LCDE=0;88.89. }//LCD写数据函数90.91. uchar read_data()92.93. {94.95. uchar read;96.97. lcd_busy();98.99. RS=1;100.101. RW=1;102.103. LCDE=0;104.105. delay(7);106.107. LCDE=1;108.109. delay(9);110.111. read=P0;112.113. LCDE=0;114.115. delay(11);;116.117.118.119. return read;120.121. } //LCD读数据函数122.123. void clear_lcd()124.125. {126.127. uchar i,j;128.129. write_com(0x34);130.131. for(i=0;i<32;i++) //因为LCD有纵坐标32格所以写三⼗⼆次132.133. {134.135. write_com(0x80+i); //先写⼊纵坐标Y的值137. write_com(0x80); //再写⼊横坐标X的值138.139. for(j=0;j<32;j++) //横坐标有16位,每位写⼊两个字节的的数据,也就写⼊32次140.141. { //因为当写⼊两个字节之后横坐标会⾃动加1,所以就不⽤再次写⼊地址了。
/******************************************************************************主程序部分******************************************************************************/ #include<reg52.h>#include<intrins.h>#include<12864.h>#include<AD9850.h>#include<IR.h>#define uchar unsigned char#define uint unsigned intuchar h1[]={"CH1: Hz "};uchar h2[]={"CH2: Hz "};uchar h3[]={"Δφ: . ° "};uchar h4[]={"V1:2.3V V2:2.3V"};long int fa=1000,fb=1000,ph=0,f=0;//定义A、B通道初始频率,初始相位,频率中间变量long int ph_disp=0;//相位显示变量,实际相位增量为11.25时,控制字增量为8long int n=0;//Vol+或V ol-按下的次数,在相位显示时用uchar h=2;//定义行参数,初始显示为第二行bit H_ok=1;//行选择完成标志位bit Num_ok=1;//数字输入完成标志位bit Step_ok=1;//步进输入完成标志位bit Sel_ok=1;//选择成功标志位bit LCD_ok=1;//写LCD完成标志位bit AD9850_ok=1;//写AD9850完成标志位void change()//将实际数值在12864上显示进行要的处理{h1[7]='0'+fa/100000;h1[8]='0'+fa/10000%10;h1[9]='0'+fa/1000%10;h1[10]='0'+fa/100%10;h1[11]='0'+fa/10%10;h1[12]='0'+fa%10;if(h==1)if(Sel_ok==1) h1[15]='*';//显示当前所在行else h1[15]='-';//数字输入等待状态显示-else h1[15]=' ';//调整项不在此行显示为空h2[7]='0'+fb/100000;h2[8]='0'+fb/10000%10;h2[9]='0'+fb/1000%10;h2[10]='0'+fb/100%10;h2[11]='0'+fb/10%10;h2[12]='0'+fb%10;if(h==2)if(Sel_ok==1) h2[15]='*';else h2[15]='-';else h2[15]=' ';ph_disp=n*100*11.25;h3[6]='0'+ph_disp/10000;h3[7]='0'+ph_disp/1000%10;h3[8]='0'+ph_disp/100%10;h3[10]='0'+ph_disp/10%10;h3[11]='0'+ph_disp%10;if(h==3)if(Sel_ok==1) h3[15]='*';else h3[15]='-';else h3[15]=' ';}void LCD_Display()//12864整屏显示{change();DisplayListChar(0,0,h1);DisplayListChar(0,1,h2);DisplayListChar(0,2,h3);DisplayListChar(0,3,h4);}void H_sel()//行参数选择{switch(IRcord[2]){case 0x1b:h--;if(h<1) h=3;H_ok=1;break;//ch+ case 0x1f:h++;if(h>3) h=1;H_ok=1;break;//ch- default:break;}irpro_ok=0;}void Step_sel(void)//步进输入{switch(IRcord[2])//判断红外遥控用户码值{case 0x1a://*********************************vol+if(h==3) {ph+=8;if(ph>0xf8)ph=0;n++;if(n>31)n=0;Step_ok=1;}elseif(h==1){ph=0;n=0;fa++;if(fa>999999) fa=999999;Step_ok=1;}if(h==2){ph=0;n=0;fb++;if(fb>999999) fb=999999;Step_ok=1;}break;case 0x1e://**********************************vol-if(h==3) {ph-=8;if(ph<0)ph=0xf8;n--;if(n<0)n=31;Step_ok=1;}elseif(h==1){ph=0;n=0;fa--;if(fa<0) fa=0;Step_ok=1;}if(h==2){ph=0;n=0;fb--;if(fb<0) fb=0;Step_ok=1;}break;default:break;}irpro_ok=0;}void Num_sel()//数字输入,频率可直接数字输入,相位步进输入{switch(IRcord[2])//判断用户码值{case 0x01://****************************************1f=f*10+1;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=0;LCD_Display();}break;case 0x02://************************************2f=f*10+2;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();}break;case 0x03://************************************3f=f*10+3;if(f>999999) f=0;Num_ok=0;Sel_ok=1;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x04://************************************4 f=f*10+4;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x05://************************************5 f=f*10+5;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x06://************************************6 f=f*10+6;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x07://************************************7 f=f*10+7;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x08://************************************8 f=f*10+8;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x09://************************************9 f=f*10+9;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x00://************************************0f=f*10;if(f>999999) f=0;Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}//if(h==3){if(f>255) f=0;ph=f;LCD_Display();} break;case 0x5c:Num_ok=1;break;//********************确定case 0x57:f=f/10;if(f>999999) f=0;//***************取消Num_ok=0;Sel_ok=0;if(h==1){fa=f;ph=0;n=0;LCD_Display();}if(h==2){fb=f;ph=0;n=0;LCD_Display();}break;default:break;}irpro_ok=0;}void Num_process()//数字输入处理{if(Num_ok==1){AD9850_ok=0;Reset_AD9850();Write_AD9850(ph,0x00,fa,fb);Sel_ok=1;f=0;AD9850_ok=1;}}void Step_process()//步进输入处理{if(Step_ok==1){AD9850_ok=0;Reset_AD9850();Write_AD9850(ph,0x00,fa,fb);AD9850_ok=1;}}void IR_process(void)//红外综合处理{if(irok)//如果红外信号接收好了进行红外数据处理{Ircordpro();irok=0;}if(irpro_ok)//如果红外数据处理好后进行其他工作处理{H_sel();Step_sel();Num_sel();}}void main(){Port_init();//端口初始化TIM0init();//定时器0初始化EX0init();//外部中断0初始化LCDInit();//12864初始化LCDClear();//12864清屏LCDClear();LCD_Display();//12864显示初始内容Reset_AD9850();//AD9850复位Reset_AD9850();//AD9850复位Write_AD9850(ph,0x00,fa,fb);//AD9850写初始数据delay_1ms(10);while(1){if( (Num_ok||Step_ok)||H_ok){LCD_Display();H_ok=0;Num_ok=0;Step_ok=0;}/*只有在各项输入选择完成后才更新显示内容避免12864因写数据时受其他影响而白屏*/IR_process();Num_process();Step_process();}}/*****************************************************12864显示部分(12864.h)*****************************************************/#include <reg52.h>sfr P4=0xe8;//STC89C52RC(TQFP封装)有P4口,入口地址为0xe8sbit LCD_RS = P4^0;sbit LCD_RW = P4^1;sbit LCD_E = P4^2;sbit LCD_PSB = P3^7;#define LCD_Data P2//12864数据口,并行传送#define BUSY 0x80 //12864忙信号ReadStatusLCD()//读12864状态{LCD_RS = 0;LCD_RW = 1;LCD_E = 0;LCD_Data = 0xFF;LCD_E = 1;while (LCD_Data & BUSY);LCD_E = 0;return(LCD_Data);}void WriteCommandLCD(unsigned char WCLCD,BusyC)//写指令{if (BusyC) ReadStatusLCD();LCD_Data = WCLCD;LCD_RS = 0;LCD_RW = 0;LCD_E = 1;LCD_E = 1;LCD_E = 1;LCD_E = 0;}void WriteDataLCD(unsigned char WDLCD)//写数据{ReadStatusLCD(); //busy testLCD_RS = 1;LCD_RW = 0;LCD_Data = WDLCD;LCD_E = 1;LCD_E = 0;LCD_E = 0;LCD_E = 1;}void LCDClear(void)//清屏{WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x34,1); //显示光标移动设置WriteCommandLCD(0x30,1); //显示开及光标设置}//显示一行字符,起始坐标为(X,Y)void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData) {switch(Y){case 0:Y =0X80;break; //根据行数来选择相应地址case 1:Y=0X90;break;case 2:Y=0X88;break;case 3:Y=0X98;break;}WriteCommandLCD( Y+X , 1); //这里不检测忙信号,发送地址码X = X*2;Y = 0;while ( DData[Y] != 0 ) //若到达字符串尾则退出{if (X <= 0x0F) //X坐标应小于0xF{WriteDataLCD(DData[Y]);X++;Y++;//Delay5Ms();}else break;}}/****************************************************38KHz红外接收头部分(IR.h)东芝TC9012编码****************************************************/#include<reg52.h>#include<stdio.h>#include<intrins.h>#define TURE 1#define FALSE 0#define uchar unsigned char#define uint unsigned intsbit IR=P3^2; //红外接口,使用外部中断0unsigned char irtime;//红外用全局变量bit irok,irpro_ok;//红外接收成功标志,红外处理完毕标志unsigned char IRcord[4];32位数据码,共4个字节unsigned char irdata[33];//每个电平的持续时间void Ir_work(void);void Ircordpro(void);void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数{irtime++; //用于计数2个下降沿之间的时间}void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数{static unsigned char i; //接收红外信号处理static bit startflag; //是否开始处理标志位if(startflag){if(irtime<63&&irtime>=33)//引导码TC9012的头码,9ms+4.5msi=0;irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=0;}}else{irtime=0;startflag=1;}}void TIM0init(void)//定时器0初始化{TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值TH0=0x00; //重载值TL0=0x00; //初始化值ET0=1; //开中断TR0=1;}void EX0init(void){IT0 = 1; //外部中断0下降沿触发EX0 = 1; //使能外部中断EA = 1; //开总中断}void Ircordpro(void)//红外码值处理函数{unsigned char i, j, k;unsigned char cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=irdata[k];if(cord>7)//大于7值为1,和晶振有关系,12M{value=value|0x80;}else{value=value;}if(j<8){value=value>>1;}k++;}IRcord[i]=value;value=0;} irpro_ok=1;//处理完毕标志位置1}void Port_init()//端口初始化{P0=0xff;P1=0xff;P2=0xff;P3=0xff;}/***********************************************AD9850部分(AD9850.h)时钟源为12M有源晶振***********************************************/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define Data__A P0//数据口,并行模式#define Data__B P1sbit WCLK_A= P3^0;//控制字装载时钟sbit FQUD_A= P3^1;//频率更新sbit REST_A= P3^3;//复位sbit WCLK_B= P3^4;sbit FQUD_B= P3^5;sbit REST_B= P3^6;/********************************AD9850的40位控制字(5字节)第一字节:高5位为相位控制字,低三位为电源和其他控制字,低3位一般取000********************************/uchar word_a[5]={0x00,0x00,0x00,0x00,0x00};uchar word_b[5]={0x00,0x00,0x00,0x00,0x00};void CHF_A(unsigned long int a)//将想要的频率和相位转为40位控制字{unsigned long int j;j=357.9139413*a; //a是A通道要输出的频率值,单位Hz,12M除以2的32次方等于357.9139413word_a[1]=j>>24;word_a[2]=j>>16;word_a[3]=j>>8;word_a[4]=j;}void CHF_B(unsigned long int b){unsigned long int k;k=357.9139413*b; //b是B通道要输出的频率值,单位Hzword_b[1]=k>>24;word_b[2]=k>>16;word_b[3]=k>>8;word_b[4]=k;}void delay_1ms(uint t){uint i,j;for(i=0;i<t;i++)for(j=0;j<120;j++);}void Reset_AD9850()//复位,并行模式{WCLK_A=0;WCLK_B=0;FQUD_A=0;FQUD_B=0;REST_A=0;REST_B=0;REST_A=1;REST_B=1;REST_A=0;REST_B=0;}//以并行方式同时向两个AD9850写控制字void Write_AD9850(uchar PH_A,uchar PH_B,unsigned long int FQ_A,unsigned long int FQ_B) {uint i;REST_A=1;REST_B=1;delay_1ms(100);WCLK_A=0;WCLK_B=0;FQUD_A=0;FQUD_B=0;REST_A=1;REST_B=1;CHF_A(FQ_A);CHF_B(FQ_B);word_a[0]=PH_A;word_b[0]=PH_B;for(i=0;i<5;i++){Data__A=word_a[i];Data__B=word_b[i];WCLK_A=1;_nop_();WCLK_B=1;_nop_();WCLK_A=0;_nop_();WCLK_B=0;_nop_();}FQUD_A=0;_nop_();FQUD_B=0;_nop_();FQUD_A=1;_nop_();FQUD_B=1;_nop_();Data__A=0x00;Data__B=0x00;}。
STC89C51单片机产生正弦波、方波、三角波LED显示频率源程序#include <stdio.h>#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit LATCH1=P2^6;//定义锁存使能端口段锁存sbit LATCH2=P2^7;// 位锁存unsigned char TempData[8]; //存储显示值的全局变量unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code DuanMa2[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};// 显示段码值0~9unsigned char code DuanMa1[3]={0x77,0x7c,0x39};unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码#define DataPort P0sbit keyA=P3^3;sbit keyB=P3^4;sbit keyC=P3^5;sbit wc=P1^0;sbit scl=P1^1;sbit sda=P1^2;sbit scl1=P1^3;sbit sda1=P1^4;sbit p5=P1^5;sbit p6=P1^6;sbit p7=P1^7;uint sign,ad;uchar temp[10], temp1[3];//定义显示区域临时存储数组uchar voltage; //定义浮点变量uchar l=0,m=100,n=0;uchar code sin[200] = {52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,75,77,78,79,81,82,83,84,85,86,88,89,90,90,91,92,93,94,95,95,96,96,97,97,98,98,98,99,99,99,99,100,100,100,100,100,9 9,99,99,99,98,98,98,97,97,96,96,95,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,79,7 8,77,75,74,73,71,70,68,67,65,64,62,61,59,58,56,55,53,52,50,48,47,45,44,42,41,39,38,3 6,34,33,32,30,29,27,26,24,23,22,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,5,4,4,3,2,2,2,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,2,2,2,3,4,4,5,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,26,27,29,30,32,33,35,36,38,39,41,42,44,45,47,48,50};void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}void delay(){ ;; }void delay1(uchar x){uchar a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}void Delay2(unsigned int t){while(--t);}void Display(){uchar i;for(i=0;i<4;i++){DataPort=WeiMa[i]; //取位码LATCH2=1; //位锁存LATCH2=0;if(i==0) DataPort=DuanMa1[sign-1];else if(i==1) DataPort=DuanMa2[temp1[i]];else DataPort=DuanMa[temp1[i]]; //取显示数据,段码LATCH1=1; //段锁存LATCH1=0;Delay2(500); // 扫描间隙延时,时间太长会闪烁,太短会造成重影}}//pcf8591void init1(){sda1=1;delay();scl1=1;delay();}void start1() //开始信号{sda1=1;delay();scl1=1;delay();sda1=0;delay();}void stop1() //停止{sda1=0;delay();scl1=1;delay();sda1=1;delay();}void respons1() //应答{uchar i;scl1=1;delay();while((sda1==1)&&(i<250))i++;scl1=0;delay();}void write_byte1(uchar date) {uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;scl1=0;delay();sda1=CY;delay();scl1=1;delay();}scl1=0;delay();sda1=1;delay();}uchar read_byte1(){uchar i,k;scl1=0;delay();sda1=1;delay();for(i=0;i<8;i++){scl1=1;delay();k=(k<<1)|sda1;scl1=0;delay();}return k;}void write_add1(uchar date) //写入DA{start1();write_byte1(0x90);respons1();write_byte1(0x40);respons1();write_byte1(date);respons1();// delay1(100);stop1();}uchar read_add1( uchar address ) //读AD值{uchar date;start1();write_byte1(0x90);respons1();write_byte1(0x40|address);respons1();start1();write_byte1(0x91);respons1();date=read_byte1();stop1();return date;}//键盘void keyscan(){if(keyA==0){delay1(10);if(keyA==0)sign=1;while(!keyA);}if(keyB==0){delay1(10);if(keyB==0)sign=2;while(!keyB);}if(keyC==0){delay1(10);if(keyC==0)sign=3;while(!keyC);}}//eepromvoid start() //开始信号{sda=1;delay();scl=1;delay();sda=0;delay();}void stop() //停止{sda=0;delay();scl=1;delay();sda=1;delay();}void respons() //应答{uchar i;scl=1;delay();while((sda==1)&&(i<250))i++;scl=0;delay();}void init(){sda=1;delay();scl=1;delay();}void write_byte(uchar date){uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;scl=0;sda=CY;delay();scl=1;delay();}scl=0;delay();sda=1;delay();}uchar read_byte(){uchar i,k;scl=0;delay();sda=1;delay();for(i=0;i<8;i++){scl=1;delay();k=(k<<1)|sda;scl=0;delay();}return k;}void write_add(uchar date[],uchar address ) {uchar i,*pdate;pdate=date;for(i=0;i<2;i++){write_byte(0xae);respons();write_byte(address+i);respons();write_byte(*(pdate+i));respons();stop();}}void read_add(uchar date[] ,uchar address ) {uchar i,*pdate;pdate=date;for(i=0;i<2;i++){start();write_byte(0xae);respons();write_byte(address+i);respons();start();write_byte(0xaf);respons();*(pdate+i)=read_byte();stop();}}void sj(){if(l<100){write_add1(l);l++;}if(l>=100&m>0){write_add1(m);m--;}if(l>=100&m<=0){l=0;m=100;}p5=0;p6=1;p7=1;}void zx(){if(l<200){write_add1(sin[l]);l++;}if(l>=200)l=0;p6=0;p7=1;p5=1;}void fb(){if(l<100){write_add1(255);l++;}if(l>=100&n<100){write_add1(0);n++;}if(l>=100&n>=100){l=0;n=0;}p7=0;p5=1;p6=1;}void main(){uchar i,num,tab[2];//定义显示区域临时存储数组wc=0;num=0;tab[0]=0;tab[1]=0;TMOD=0x21;//设置定时器1为工作方式2定时器0为工作方式1 TH1=0xfd;TL1=0xfd;TR1=1;REN=1;SM0=0;SM1=1;EA=1;ES=1;init();init1();for(i=0;i<5;i++)num=read_add1(0);read_add(tab,1);sign=tab[0];ad=(uint)num*100;TH0=(65536-ad)/256;TL0=(65536-ad)%256;ET0=1; //定时器中断打开TR0=1;while(1){keyscan();for(i=0;i<5;i++)num=read_add1(0);voltage=500/num;ad=(uint)num*100;tab[0]=sign;tab[1]=ad;write_add(tab,1);num=read_add1(0);voltage=500/num;temp1[0]=voltage/100;temp1[1]=(voltage%100)/10;temp1[2]=voltage%1000;Display();}}void ser() interrupt 4{RI=0;sign=SBUF;}void T0_time() interrupt 1{ad=(uint)read_add1(0)*100;TH0=(65536-ad)/256;TL0=(65536-ad)%256;if(sign==1) sj(); if(sign==2) zx(); if(sign==3) fb(); }。
#include<reg52.h>#include"math.h"#define uint unsigned int#define uchar unsigned charextern void_nop_(void);uint shu=0xffff,shu1;uchar q,gao=63,gw=0x80,dw=0x00,n1=0x80,n3=0,n5=0,n6=0x80; float n2,n4;uchar table[8]={0,0,0,0,0,0,0,0};sbit LCD_CS=P2^6;sbit LCD_STD=P2^5;sbit LCD_SCLK=P2^7;void delay_us(uchar x){while(x--);}void delay_ms(uint z){uint x,y;for(x=z;x>0;x--)for(y=240;y>0;y--);}void d()//延时子程序{unsigned char i;for(i=0;i<80;i++);}void LCD_write_byte(uchar temp)//写一个字节{uchar i;for(i=8;i>0;i--){temp<<=1;LCD_STD=CY;_nop_();//延时0.5usLCD_SCLK=1;_nop_();//延时0.5usLCD_SCLK=0;}}unsigned char read_RAM()//测试是否忙{unsigned char BF;BF=0X00;return BF;}void busy()//测试是否忙{d();d();}void w_byte(uchar tmp)//写汉字{uchar temp;delay_us(25);temp=tmp<<4;tmp&=0xf0;LCD_SCLK=0;LCD_CS=1;LCD_write_byte(0xfa);LCD_write_byte(tmp);LCD_write_byte(temp);LCD_CS=0;LCD_SCLK=0;delay_us(25);}void w_com(uchar tmp)//写命令子程序{uchar temp;delay_us(25);temp=tmp<<4;tmp&=0xf0;LCD_SCLK=0;LCD_CS=1;LCD_write_byte(0xf8);LCD_write_byte(tmp);LCD_write_byte(temp);LCD_CS=0;LCD_SCLK=0;delay_us(25);}#define xoffset1//偏移量#define yoffset1void curve(unsigned char xlable,unsigned char ylable,bit dot){unsigned char H[1]={0};//读RAM寄存unsigned char L[1]={0};unsigned char xbuf;w_com(0x01);w_com(0x34);w_com(0x36);//功能设置:一次送8位数据,扩展指令集xlable=xlable+xoffset;//求相对零点ylable=ylable+yoffset;if(xlable<0)xlable=-1;//超出边界处理if(ylable<0)ylable=0;if(ylable>64)ylable=65;xbuf=xlable%16;//xlable=xlable/16;if(ylable>32)//上半屏{ylable=64-ylable;//切换上下屏xbuf=15-xbuf;//x坐标归位w_com(0x80|ylable);//输入垂直地址w_com(0x80|xlable);//输入水平地址read_RAM();//屏蔽if(xbuf>7){if(dot==0)H[0]=read_RAM()&(~(1<<xbuf-8));//擦点elseH[0]=read_RAM()|1<<xbuf-8;//插点,需要打的点L[0]=read_RAM();}else{H[0]=read_RAM();//插点,需要打的点if(dot==0)L[0]=read_RAM()&(~(1<<xbuf));//擦点elseL[0]=read_RAM()|1<<xbuf;}if(n3==0){n1=n1|n6;gw=n1;dw=0x00;}if(n3==1){n1=n1|n6;dw=n1;}if(n3==2){n1=n6;gw=n1;dw=0x00;}if(n3==3){n1=n6;dw=n1;}w_com(0x80|ylable);//输入垂直地址w_com(0x80|xlable);//输入水平地址w_byte(gw);w_byte(dw);}else//下半屏{ylable=32-ylable;xbuf=15-xbuf;//x坐标归位w_com(0x80|ylable);//输入垂直地址w_com(0x88|xlable);//输入水平地址read_RAM();//屏蔽if(xbuf>7){if(dot==0)H[0]=read_RAM()&(~(1<<xbuf-8));//擦点elseH[0]=read_RAM()|1<<xbuf-8;//插点,需要打的点L[0]=read_RAM();}else{H[0]=read_RAM();//插点,需要打的点if(dot==0)L[0]=read_RAM()&(~(1<<xbuf));//擦点elseL[0]=read_RAM()|1<<xbuf;}w_com(0x80|ylable);//输入垂直地址w_com(0x88|xlable);//输入水平地址w_byte(H[0]);w_byte(L[0]);}}//清除屏幕void BMP_clear(void){unsigned char i,j;unsigned char L[1]={0};w_com(0x34);//8Bit扩充指令集,即使是36H也要写两次w_com(0x36);//绘图ON,基本指令集里面36H不能开绘图for(i=0;i<32;i++)//12864实际为256x32{w_com(0x80|i);//行位置w_com(0x80);//列位置for(j=0;j<32;j++)//256/8=32bytew_byte(~(0xff));}}sine_wave(unsigned char H,unsigned char off,bit dot){float i;for(i=0;i<1;i++){curve(0,H*sin(i/127*6.28)+off,dot);}}main(){w_com(0x01);//清屏幕w_com(0x30);//功能设定,设为基本功能w_com(0x02);//DDRAM的地址设为'00H'w_com(0x0D);//游标右移w_com(0xff);//开显示w_com(0x0c);//关闭光标w_com(0x01);//清屏幕显示BMP_clear();while(1){for(n4=3;n4<7;n4++){n6=0x80;n1=0x80;for(n2=0;n2<8;n2++){n3=2;//table[n5]=n1;curve(n4,gao,1);gao--;if(n2!=8)n6>>=1;n5++;delay_ms(50);}n1=0x80;n6=0x80;for(n2=0;n2<8;n2++){//gw=table[n5];n3=1;curve(n4,gao,1);//gao++;if(n2!=8)n6>>=1;n5--;delay_ms(50);}}while(1);}}。
单片机产生正弦波
单片机产生正弦波可以通过使用数字信号合成技术来实现。
以下是一种常见的实现方法:
1. 首先,准备一个包含一周期正弦波的查表数组,数组长度为一个周期内所需的采样点数。
可以使用固定的采样频率(如
8kHz)和固定的振幅。
数组的内容为一个周期内的正弦波的
采样值,可以使用查表或者数学计算来生成。
2. 使用定时器产生固定的中断频率,生成一个固定的时间间隔,由于波形是连续的,通常采用中断的方式来生成波形。
3. 在每个定时器中断中,读取查表数组的对应位置的值,并通过DAC(数字到模拟转换器)输出到外部接口(如扬声器)。
4. 根据查表数组长度和定时器中断频率的选择,可以调整正弦波的频率(调整定时器中断频率)和振幅(调整查表数组中的采样值)。
需要注意的是,单片机的处理能力和外设的性能限制了可生成的最高频率,同时,由于数字信号合成存在理论上的误差,生成的波形可能并不完美。
因此,具体的实现方式还需要根据单片机型号和额外硬件资源来调整。
/**************************************//* 信号发生器(正弦波,方波,三角波)*/ /*************************************/#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit cs=P2^0;sbit clk=P2^1;sbit din=P2^2;sbit key1=P1^0;sbit key2=P1^1; uchar keydat;uchar flag;被置零立马停止发信号//tlc5615 片选端口//tlc5615 时钟线//tlc5615 传输端口//按键的单片机接口//波形发生终止信号的标志位一旦uchar m,num; uchar dat=0xff;uchar code tosin[141]={//正弦波的编码0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16, 0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b, 0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45, 0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63, 0x66,0x69,0x6c,0x6f,0x70,0x71,0x72,0x73,0x74,0x75, 0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7e, 0x7f,0x80,0x7f,0x7e,0x7e,0x7d,0x7c,0x7b,0x7a,0x79, 0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x6f,0x6c,0x69, 0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c, 0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30, 0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a, 0x18,0x16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a, 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01, 0x00};uchar flagsqu; 中断控制)// 方波高低电平控制为 (运用定时器 1void delay(uchar z) //延时函数{uchar x,y;for(x=0;x<110;x++)for(y=z;y>0;y--);}void prepare() {cs=1;din=1;clk=0;cs=0; 为低时进? //tlc5615 的初始化//cs 的上升沿和下降沿必须在clk}/* 用中断来产生方波void Squtranslator(){TR1=1;的持续时间占空比//启动定时器 1 控制高低电平do{do{_wave=0;}while((!flagsqu) && flag==1);// 如果一旦终止信号的//产生可以立马退出循环flagsqu=0;do{_wave=1;}while((!flagsqu) && flag==1); flagsqu=0; }while(flag);flag=1;TR1=0;}*/void Squtranslator() //方波函数{uchar j;uchar dat1=0x7f;while(flag){do{}prepare();dat=dat1;for(j=0;j<12;j++) { din=(bit)(dat>>7);clk=1;dat=dat<<1; clk=0;}cs=1;为低时进行delay(200);if(dat1==0)dat1=0x7f;elsedat1=0;}while(flag);}//将数据的最高位赋给din//一位位的传输//cs 的上升沿和下降沿必须在//使高低电平持续一段时间//完成了0和0x7f 之间的替换clkvoid Tratranslator() //锯齿波的发生函数{uchar j;uchar dat1=0x7f;while(flag){do{prepare();dat=dat1;for(j=0;j<12;j++){din=(bit)(dat>>7);clk=1;dat=dat<<1;clk=0;}cs=1;为低时进行delay(2);dat1--;}while(flag && dat1);do{//将数据的最高位赋给din//一位位的传输//cs 的上升沿和下降沿必须在//稍加延时//一旦有终止信号就可以停止clk{uchar i,j;prepare(); dat=dat1; for(j=0;j<12;j++){din=(bit)(dat>>7); //将数据的最高位赋给 dindelay(2); dat1++;}while(flag && (!(dat1==0x7f)));}}void Sintranslator(uchar wave[],uchar num )//正弦波的转换函数clk=1; dat=dat<<1; clk=0;}cs=1;为低时进行//一位位的传输//cs 的上升沿和下降沿必须在clk//稍加延时uchar dat1;do{for(i=0;i<num;i++){prepare();dat1=wave[i]; //打开片选开始工作for(j=0;j<12;j++){din=(bit)(dat1>>7); //将数据的最高位赋给dinclk=1;dat1=dat1<<1; //一位位的传输clk=0;if(flag==0)break;}cs=1; //cs 的上升沿和下降沿必须在clk 为低时进行delay(1); //稍加延时if(flag==0)break;}}while(flag); //等待控制键的暂停}void keyscan() //切换功能按键返回键值函数{uchar i;for(i=0;i<4;i++){if(key1==0){delay(10);if(key1==0){keydat++;do{}while(!key1); //松手检测if(keydat==4)keydat=1;//加满回零处理}}}}void keycountrl() // 切断输出控制函数{if(key2==0){delay(10);{case 1:if(key2==0)flag=0;do{}while(!key2); //松手检测}}}void main (){uchar temp;TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;while(1){do{switch(keydat)//确定定时器的工作方式 //给定时器 0 赋予初值 //开总中断 //开启定时器 0 中断flag=1;do{Sintranslator(tosin,141);}while(flag);break;case 2: flag=1;do{Tratranslator();}while(flag);break;case 3: flag=1;do{Squtranslator();}while(flag);break;default:break;}}while(flag);temp=keydat; // 装载键值while(keydat==temp); // 在这里等待键值的改变}}void Time0() interrupt 1{TH0=(65536-50000)/256; //定时器0 用来扫描按键不断地扫描dTL0=(65536-50000)%256;num++;if(num==4){keyscan();keycountrl();num=0;}}。
单片机产生方波、锯齿波、三角波程序单片机产生方波、锯齿波、三角波程序单片机产生方波、锯齿波、三角波程序#include<reg51.h>#define uchar unsigned char#define uint unsigned intunsigned char x=0,m=0,y=128;sbit WR_DA=P2^1;sbit CS_DA=P2^0;//DA与单片机的接口sbit S0=P3^0; //波形选择,每次按下将产生不同的波形sbit S1=P3^1; //频率减sbit S2=P3^2; //频率加sbit S3=P3^3; //调节方波的占空比uchar code SinTab[256]={0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x 9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf ,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe 1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5 ,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0x ef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda ,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xb c,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99 ,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0 x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x 51,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0 x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x 16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0 x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0 x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x 15,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0 x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x 4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0 x72,0x76,0x79,0x7c,0x80 };void delayms(uint t){uint i;while(t--){for (i=0;i<125;i++);//对于11.0592M时钟,约延时1ms}}void delay(uint t){uint i;for (i=t;i>0;i--);}void time0_init(){TMOD|=0x01; //定时器设置 16位TH0=-50000/256;TL0=-50000%256;//初始化值ET0=1;TR0=1;EA=1;}void time0_int(void) interrupt 1 {TR0=0;//关闭定时器TH0=-50000/256;TL0=-50000%256;//重装初值if(S0==0){delayms(10);//按键消抖if(S0==0) m++;while(!S0);//松手检测}if(S1==0){delayms(10);if(S1==0) x=x+1;while(!S1);//松手检测}if(S2==0){delayms(10);if(S2==0) x=x-1;while(!S2);//松手检测}if(S3==0){delayms(10);if(S3==0) y=y+5; while(!S3);//松手检测}if(y>254) y=0;if(m>5) m=0;if(x>50) x=0;TR0=1;//启动定时器}void fangbo() //方波{uchar i,j;j=255-y;CS_DA=0;WR_DA=0;for(i=y;i>0;i--){P0=0;delay(x);}while(j--){P0=255;delay(x);}}void juchi() //锯齿波{CS_DA=0;WR_DA=0;for(i=255;i>0;i--){P0=i;delay(x);}}void sanjiao() //三角波{uchar i;CS_DA=0;WR_DA=0;for(i=0;i<255;i++){P0=i;delay(x);}while(i--){P0=i;delay(x);}}void tixing() //梯形波{uchar i=255,j,k;CS_DA=0;WR_DA=0;{P0=i;delay(x);}for(j=0;j<100;j++) {P0=0;delay(x);}for(k=0;k<255;k++) {P0=k;delay(x);}}void sin() //正弦波{uchar a;CS_DA=0;WR_DA=0;for(a=0;a<255;a++) {P0=SinTab[a]; delay(x);}}main(){time0_init(); while(1){switch(m){case 0:fangbo(); //方波break;case 1:juchi(); //锯齿波break;case 2:sanjiao(); //三角波break;case 3:sin(); //正弦波break;case 4:tixing(); //梯形波break; default: fangbo(); }}}。
正弦波的源程序:(一),用到的函数1,f2t函数function x=f2t(X)global dt df t f T N%x=f2t(X)%x为时域的取样值矢量%X为x的傅氏变换%X与x长度相同并为2的整幂%本函数需要一个全局变量dt(时域取样间隔) X=[X(N/2+1:N),X(1:N/2)];x=ifft(X)/dt;end2,t2f函数。
function X=t2f(x)global dt df N t f T%X=t2f(x)%x为时域的取样值矢量%X为x的傅氏变换%X与x长度相同,并为2的整幂。
%本函数需要一个全局变量dt(时域取样间隔) H=fft(x);X=[H(N/2+1:N),H(1:N/2)]*dt;end(二),主程序。
1,%(1)绘出正弦信号波形及频谱global dt df t f Nclose allk=input('取样点数=2^k, k取10左右');if isempty(k), k=10; endf0=input('f0=取1(kz)左右');if isempty(f0), f0=1; endN=2^k;dt=0.01; %msdf=1/(N*dt); %KHzT=N*dt; %截短时间Bs=N*df/2; %系统带宽f=[-Bs+df/2:df:Bs]; %频域横坐标t=[-T/2+dt/2:dt:T/2]; %时域横坐标s=sin(2*pi*f0*t); %输入的正弦信号S=t2f(s); %S是s的傅氏变换a=f2t(S); %a是S的傅氏反变换a=real(a);as=abs(S);subplot(2,1,1) %输出的频谱plot(f,as,'b');gridaxis([-2*f0,+2*f0,min(as),max(as)]) xlabel('f (KHz)')ylabel('|S(f)| (V/KHz)') %figure(2) subplot(2,1,2)plot(t,a,'black') %输出信号波形画图gridaxis([-2/f0,+2/f0,-1.5,1.5])xlabel('t(ms)')ylabel('a(t)(V)')gtext('频谱图')升余弦滚降系统的源程序:(一),用到的函数f2t函数和t2f函数。
单片机产生正弦波1. 简介单片机是一种集成电路,具有处理和控制功能。
它可以通过编程实现各种功能,如产生正弦波。
正弦波是一种周期性的波形,广泛应用于电子设备和通信系统中。
在本文中,将介绍如何使用单片机来产生正弦波,并详细解释实现的原理和步骤。
2. 实现原理产生正弦波的原理是利用单片机的数字输出引脚和定时器功能。
单片机的数字输出引脚可以输出高电平和低电平,通过不断变换输出引脚的状态,可以模拟出正弦波的波形。
具体步骤如下: 1. 设置单片机的定时器,使其按照一定的频率产生中断信号。
2. 在中断服务函数中,根据正弦波的波形特点,设置数字输出引脚的状态,使其输出对应的高电平或低电平。
3. 循环执行中断服务函数,不断更新数字输出引脚的状态,从而产生连续的正弦波。
3. 编程实现以下是使用C语言编写的单片机产生正弦波的示例代码:#include <reg52.h>// 定义正弦波的周期和振幅#define PERIOD 100#define AMPLITUDE 127// 正弦波数据表unsigned char sineTable[] = {128, 140, 151, 162, 173, 183, 192, 200, 207, 213, 218, 222, 225, 227, 228,229,229, 229, 227, 225, 222, 218, 213, 207, 200, 192, 183, 173, 162, 151, 140,128,115, 104, 93, 82, 71, 61, 52, 44, 37, 31, 26, 22, 19, 17, 16, 15,15, 15, 17, 19, 22, 26, 31, 37, 44, 52, 61, 71, 82, 93, 104, 115};// 定时器中断服务函数void timerInterrupt() interrupt 1 {static unsigned char index = 0;TH0 = (65536 - PERIOD) / 256; // 设置定时器初值TL0 = (65536 - PERIOD) % 256;P1 = AMPLITUDE + sineTable[index]; // 设置输出引脚的状态index = (index + 1) % sizeof(sineTable); // 更新正弦波数据表的索引}void main() {TMOD = 0x01; // 设置定时器0为工作模式1TH0 = (65536 - PERIOD) / 256; // 设置定时器初值TL0 = (65536 - PERIOD) % 256;ET0 = 1; // 允许定时器0中断EA = 1; // 允许总中断TR0 = 1; // 启动定时器0while (1);}在上述代码中,使用了8051系列的单片机,使用了定时器0来产生中断信号,并在中断服务函数中根据正弦波数据表的值设置输出引脚的状态。
单片机产生正弦波然后放大概述说明以及解释1. 引言1.1 概述本文旨在探讨单片机产生正弦波并进行放大的方法与实现,以及相关的原理、设计方案和实验结果。
正弦波是一种重要的信号形式,在各种电子设备和通信系统中广泛应用。
利用单片机生成正弦波,并经过放大器放大后,可以得到更稳定、可控的正弦波信号,有助于满足不同场景下的需求。
1.2 文章结构本文主要分为五个部分:引言、单片机产生正弦波、正弦波放大器设计、实验结果与分析以及结论与展望。
引言部分将对文章进行概述说明,并介绍文章的结构安排;随后,将在接下来三个部分依次详细介绍单片机产生正弦波的原理与实现方法,正弦波放大器的设计与构建以及性能优化与测试方法;接着,在第四部分中将提供实验结果,并对产生效果和输出性能进行评估和分析;最后,在结论与展望部分总结整篇文章,并提出未来发展方向建议。
1.3 目的本文的目标是通过对单片机产生正弦波并进行放大的研究,探索一种有效可行的方法和设计方案。
通过实验结果和分析,对该方法进行评估,并提出可能存在的问题以及未来改进的方向,以期为相关领域的研究与开发提供参考和借鉴。
同时,也希望通过本文的介绍和说明,增进读者对单片机产生正弦波并进行放大的技术理解和应用意义。
2. 单片机产生正弦波2.1 原理介绍单片机是一种微型计算机系统,具有集成度高、功耗低、体积小等特点。
它能够通过内部的时钟电路和计数器来生成不同频率的方波信号,并通过数字滤波器将方波信号转换为近似连续的正弦波信号。
这种方法称为数字合成技术,可用于实现正弦波发生器。
2.2 实现方法在单片机中,可以使用PWM(脉冲宽度调制)技术来产生正弦波。
PWM技术是通过控制脉冲信号的占空比来调节输出电压的高低电平,从而实现对正弦波频率和幅值的控制。
具体而言,可以选择一个定时器作为基准时钟源,并设置相关寄存器来控制定时器工作模式和产生脉冲信号的频率、占空比等参数。
然后,在定时器溢出中断函数中更新输出引脚状态,使其按照预设的占空比在高、低电平之间切换。
电子科技大学吴鉴鹰#include <c8051f020.h> // SFR declarations#include <intrins.h>#include <stdio.h>#include<math.h>#define uchar unsigned char#define uint unsigned intuchar i,j,colour=1,T=0;#define Lcd_Bus P5/*char code seg[360] = {0x80,0x82,0x84,0x86,0x88,0x8b,0x8d,0x8f,0x91,0x94, 0x96,0x98,0x9a,0x9c,0x9e,0xa1,0xa3,0xa5,0xa7,0xa9, 0xab,0xad,0xaf,0xb1,0xb4,0xb6,0xb8,0xba,0xbc,0xbe, 0xbf,0xc1,0xc3,0xc5,0xc7,0xc9,0xcb,0xcc,0xce,0xd0, 0xd2,0xd3,0xd5,0xd7,0xd8,0xda,0xdc,0xdd,0xdf,0xe0, 0xe2,0xe3,0xe4,0xe6,0xe7,0xe8,0xea,0xeb,0xec,0xed, 0xee,0xef,0xf0,0xf2,0xf3,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xf9,0xfa,0xfb,0xfb,0xfc,0xfc,0xfd,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfb,0xfb,0xfa,0xf9,0xf9,/*0xf8,0xf7,0xf6,0xf5,0xf4,0xf4,0xf3,0xf2,0xf1,0xf0, 0xee,0xed,0xec,0xeb,0xea,0xe8,0xe7,0xe6,0xe4,0xe3, 0xe2,0xe0,0xdf,0xdd,0xdc,0xda,0xd9,0xd7,0xd5,0xd4, 0xd2,0xd0,0xce,0xcd,0xcb,0xc9,0xc7,0xc5,0xc3,0xc2, 0xc0,0xbe,0xbc,0xba,0xb8,0xb6,0xb4,0xb2,0xb0,0xae, 0xab,0xa9,0xa7,0xa5,0xa3,0xa1,0x9f,0x9c,0x9a,0x98, 0x96,0x94,0x92,0x8f,0x8d,0x8b,0x89,0x86,0x84,0x82, 0x80,0x7d,0x7b,0x79,0x77,0x75,0x72,0x70,0x6e,0x6c, 0x69,0x67,0x65,0x63,0x61,0x5f,0x5c,0x5a,0x58,0x56, 0x54,0x52,0x50,0x4e,0x4c,0x4a,0x48,0x46,0x44,0x42, 0x40,0x3e,0x3c,0x3a,0x38,0x36,0x34,0x33,0x31,0x2f, 0x2d,0x2c,0x2a,0x28,0x27,0x25,0x24,0x22,0x21,0x1f, 0x1e,0x1c,0x1b,0x19,0x18,0x17,0x16,0x14,0x13,0x12, 0x11,0x10,0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,0x7, 0x7, 0x6, 0x5, 0x5, 0x4, 0x3, 0x3, 0x2, 0x2,0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1,0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x6, 0x6,0x7, 0x8, 0x9, 0xa, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,0x10,0x12,0x13,0x14,0x15,0x16,0x18,0x19,0x1a,0x1c, 0x1d,0x1f,0x20,0x22,0x23,0x25,0x26,0x28,0x2a,0x2b, 0x2d,0x2f,0x30,0x32,0x34,0x36,0x38,0x39,0x3b,0x3d, 0x3f,0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f,0x51,0x53,0x55,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x65,0x67,0x69,0x6b,0x6d,0x70,0x72,0x74,0x76,0x78,0x7b,0x7d};*/#define SYSCLK 22118400 // SYSCLK frequency in Hz #define INT_DEC 256 // integrate and decimate ratio #define _Nop() _nop_()//#define FIRST_ADDR 0//-----------------------------------------------------------------------------// 16-bit SFR Definitions for 'F02x//-----------------------------------------------------------------------------sfr16 DP = 0x82; // data pointersfr16 TMR3RL = 0x92; // Timer3 reload valuesfr16 TMR3 = 0x94; // Timer3 countersfr16 ADC0 = 0xbe; // ADC0 datasfr16 ADC0GT = 0xc4; // ADC0 greater than window sfr16 ADC0LT = 0xc6; // ADC0 less than windowsfr16 RCAP2 = 0xca; // Timer2 capture/reloadsfr16 T2 = 0xcc; // Timer2sfr16 RCAP4 = 0xe4; // Timer4 capture/reloadsfr16 T4 = 0xf4; // Timer4sfr16 DAC0 = 0xd2; // DAC0 datasfr16 DAC1 = 0xd5; // DAC1 data//-----------------------------------------------------------------------------// 液晶接口定义//-----------------------------------------------------------------------------//#define LEDCTL0Low P4&=~0x01;//#define LEDCTL0High P4|=0x01;#define LCDELow P4&=~0x02;#define LCDEHigh P4|=0x02;#define LCDRWLow P4&=~0x04;#define LCDRWHigh P4|=0x04;#define LCDRSLow P4&=~0x08;#define LCDRSHigh P4|=0x08;#define LCDPSBLow P4&=~0x10;#define LCDPSBHigh P4|=0x10;//==============================//uchar num;uint delay_time;/*-----------------------------------------------------*/void SYSCLK_Init (void);void PORT_Init (void);//----------------------------------------------------------------------------- ////-----------------------------------------------------------------------------void delay(unsigned int t){ unsigned int k,j;for(k=0;k<t;k++)for(j=0;j<10;j++) ;}/*void delay(unsigned int t){unsigned int i,j ;for(i=0;i<t;i++)for(j=0;j<10;j++);}*///----------------------------------------------------------------------------- ////-----------------------------------------------------------------------------void delay18(uint k){ while(k){ k--; }}//----------------------------------------------------------------------------- // 液晶显示写命令//----------------------------------------------------------------------------- void write_com(unsigned char cmdcode){LCDRSLow;LCDRWLow;LCDEHigh;Lcd_Bus=cmdcode;delay(50);delay(60); //在数据写入的时候加入适当的延时LCDELow;delay(50);delay(60);}//-----------------------------------------------------------------------------// 液晶显示写数据//-----------------------------------------------------------------------------void write_data(unsigned char Dispdata){LCDRSHigh;LCDRWLow;LCDEHigh;Lcd_Bus=Dispdata;delay(50);delay(60); // 在数据写入的时候加入适当的延时LCDELow;delay(50);delay(60);}void chk_busy(){LCDRSLow;LCDRWHigh;LCDEHigh;Lcd_Bus=0xff ;while((Lcd_Bus&0x80)==0x80);LCDELow;}/*------------------写命令到LCD------------------------------*//*void write_com(unsigned char cmdcode){chk_busy();LCDRSLow ;LCDRWLow ;LCDEHigh ;Lcd_Bus=cmdcode ;delay(5);//------------------在数据写入的时候加入适当的延时LCDELow ;delay(5);}*//*-------------------写数据到LCD----------------------------*//*void write_data(unsigned char Dispdata){chk_busy();LCDRSHigh ;LCDRWLow ;LCDEHigh ;Lcd_Bus=Dispdata ;delay(5);//------------------在数据写入的时候加入适当的延时LCDELow ;delay(5);}*///-----------------------------------------------------------------------------// 液晶显示,复位初始//-----------------------------------------------------------------------------void lcdreset(){delay(200);delay(250);write_com(0x30);delay(100);delay(250); //选择基本指令集write_com(0x30); //选择8bit数据流delay(50);delay(250);write_com(0x0c); //开显示(无游标、不反白)delay(50);delay(250);write_com(0x01); //清除显示,并且设定地址指针为00Hdelay(50);delay(250);write_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位}//-----------------------------------------------------------------------------// 液晶显示//-----------------------------------------------------------------------------/*void display(unsigned char code *s){while(*s>0){ write_data(*s);s++;delay(50);delay(100);}}*/void hzkdis(unsigned char code*s){while(*s>0){write_data(*s);s++;delay(50);}}/*------------------首屏显示--------------------------*///-----------------------------------------------------------------------------// 液晶显示内容//-----------------------------------------------------------------------------/*void zero_screen(){write_com(0x01);delay18(10000);//write_com(0x80);//display("电子科技大学");write_com(0x90);//display("省单片机精品课程");display("C8051F020 开发板");write_com(0x88);//display("C8051F020 开发板");display(" QQ:1811728618 ");//write_com(0x98);//display(" QQ:1811728618 ");}*//*------------------显示字符串--------------------------*/void ceshi(){write_com(0x01);//清除显示,并且设定地址指针为00Hdelay(5);write_com(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)hzkdis("电子科技大学");write_com(0x90);//第二行(如果是地址是:90H,即LCD的第二行的第一个位置显示)hzkdis("通信与信息工程");write_com(0x88);//第三行(如果是地址是:88H,即LCD的第二行的第一个位置显示)hzkdis("电子信息工程");write_com(0x98);//第四行(如果是地址是:98H,即LCD的第二行的第一个位置显示)hzkdis("郑海波测试程序");}/*------------------初始化LCD屏--------------------------*//*void lcdreset(){LCDPSBHigh;delay(2000);write_com(0x30);delay(10);//选择基本指令集write_com(0x30);//选择8bit数据流delay(5);write_com(0x0c);//开显示(无游标、不反白)delay(10);write_com(0x01);//清除显示,并且设定地址指针为00Hdelay(500);write_com(0x06);//指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位delay(0);}*///-----------------------------------------------------------------------------// 通用I/O口及交叉开关初始化//-----------------------------------------------------------------------------void PORT_Init (void){XBR2 = 0x40; // 交叉开关使能P74OUT=0xff;}//-----------------------------------------------------------------------------// 系统时钟初始化//-----------------------------------------------------------------------------/*void SYSCLK_Init() 本来就不用的{OSCICN =0x87; //使用内部时钟16Mwhile((OSCICN & 0x10)==0);//内部时钟按设定频率运行}*/// 配置系统时钟使用外部晶振11.0592MHzvoid SYSCLK_Init (void){int i; // delay counterOSCXCN = 0x67; // start external oscillator with// 22.1184MHz crystal for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms)while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settleOSCICN = 0x88; // select external oscillator as SYSCLK// source and enable missing clock// detector}//-----------------------------------------------------------------------------// 系统初始化//-----------------------------------------------------------------------------void init(){SYSCLK_Init();PORT_Init ();lcdreset();//zero_screen();}//-----------------------------------------------------------------------------// 主程序//-----------------------------------------------------------------------------/*void main(){WDTCN = 0xde;WDTCN = 0xad; //禁止看门狗定时器LCDPSBHigh;//LCDRSTHigh;init();zero_screen();P5=0xff;while(1){}} *///------------定义接口-------------///*sbit RS=P2^2 ;sbit RW=P2^3 ;sbit E=P2^4;sbit PSB= P2^5; //H=并口; L="串口";#define Lcd_Bus P0// P0 接LCM#define uchar unsigned char*///定义字符/汉字显示起始位置/*------------------检查忙位-----------------------------*//*------------------延时子程序-----------------------------*///------------------清整个GDRAM空间---------------------------- void clrgdram(){unsigned char x,y ;for(y=0;y<64;y++)for(x=0;x<16;x++){write_com(0x34);write_com(y+0x80);//行地址write_com(x+0x80);//列地址write_com(0x30);write_data(0x00);write_data(0x00);}}//------------------------------------------------------------void clrscreen(){write_com(0x01);delay(10);}unsigned char ReadByte(void){unsigned char byReturnValue ;chk_busy();Lcd_Bus=0xff ;LCDRSHigh ;LCDRWHigh ;LCDELow ;LCDEHigh;byReturnValue=Lcd_Bus ;LCDELow ;return byReturnValue ;}/*增加画点子程序函数功能:在坐标为(x,y)点画一个点参数意义X:12864屏幕的横坐标,范围是0到128(从左到右)Y:12864的纵坐标,范围是0到64(从上到下)Color:为1的时候表示为黑点*//*void DrawPoint(unsigned char X,unsigned char Y,unsigned char Color) {unsigned char Row,Tier,Tier_bit ;unsigned char ReadOldH,ReadOldL ;write_com(0x34);write_com(0x36);Tier=X>>4 ;Tier_bit=X&0x0f ;if(Y<32){Row=Y ;}{Row=Y-32 ;Tier+=8 ;}write_com(Row+0x80);write_com(Tier+0x80);ReadByte();ReadOldH=ReadByte();ReadOldL=ReadByte();write_com(Row+0x80);write_com(Tier+0x80);if(Tier_bit<8){switch(Color){case 0 :ReadOldH&=(~(0x01<<(7-Tier_bit))); break ;case 1 :ReadOldH|=((0x01<<(7-Tier_bit))); break ;case 2 :ReadOldH^=(0x01<<(7-Tier_bit)); break ;default :break ;}write_data(ReadOldH);write_data(ReadOldL);}else{switch(Color){case 0 :ReadOldL&=(~(0x01<<(15-Tier_bit))); break ;case 1 :ReadOldL|=((0x01<<(15-Tier_bit))); break ;case 2 :ReadOldL^=(0x01<<(15-Tier_bit)); break ;break ;}write_data(ReadOldH);write_data(ReadOldL);}write_com(0x30);}void main(void){//WDTCN = 0xde; // 关闭WDT//WDTCN = 0xad;SYSCLK_Init ();PORT_Init ();//LCDRWLow;//lcdreset();//zero_screen();//clrgdram();delay(2000);clrscreen();while(1){for(i=0;i<128;i++){/*unsigned char k;if(j>0x32) k=seg[i];else k=-seg[i];j=0x32-k;*//*j=sin(i);DrawPoint(i,j,colour);}//T+=4;delay(5000);}while(1);}*/void DrawPoint(unsigned char X,unsigned char Y,unsigned char Color) {unsigned char Row,Tier,Tier_bit ;unsigned char ReadOldH,ReadOldL ;write_com(0x34);write_com(0x36);Tier=X>>4 ;Tier_bit=X&0x0f ;{Row=Y ;}else{Row=Y-32 ;Tier+=8 ;}write_com(Row+0x80);write_com(Tier+0x80);ReadByte();ReadOldH=ReadByte();ReadOldL=ReadByte();write_com(Row+0x80);write_com(Tier+0x80);if(Tier_bit<8){switch(Color){case 0 :ReadOldH&=(~(0x01<<(7-Tier_bit))); break ;case 1 :ReadOldH|=(0x01<<(7-Tier_bit)); break ;case 2 :ReadOldH^=(0x01<<(7-Tier_bit)); break ;default :break ;}write_data(ReadOldH);write_data(ReadOldL);}else{switch(Color){case 0 :ReadOldL&=(~(0x01<<(15-Tier_bit))); break ;case 1 :ReadOldL|=(0x01<<(15-Tier_bit));case 2 :ReadOldL^=(0x01<<(15-Tier_bit)); break ;default :break ;}write_data(ReadOldH);write_data(ReadOldL);}write_com(0x30);}void main(void){uchar i,j,colour=1,T=0; LCDRWLow ;lcdreset();ceshi();clrgdram();delay(2000);clrscreen();while(1){for(i=0;i<128;i++){j=32-32*sin(2*i*3.14/(64+T)); DrawPoint(i,j,colour);}//T+=4;delay(5000);}while(1);}。