51单片机和dac0832输出方波、矩形波和正弦波由液晶1602显示的c语言程序

合集下载

STC51单片机的函数信号发生器(c语言)

STC51单片机的函数信号发生器(c语言)

STC51单片机的函数信号发生器(c语言)————————————————————————————————作者:————————————————————————————————日期:基于51单片机的函数信号发生器设计报告摘要本系统利用单片机AT89C52采用程序设计方法产生锯齿波、三角波、正弦波、方波四种波形,再通过D/A转换器DAC0832将数字信号转换成模拟信号,滤波放大,最终由示波器显示出来,能产生10Hz—10kHz的波形。

通过键盘来控制四种波形的类型选择、拨码开关控制频率的变化,并通过液晶屏1602显示其各自的类型以及数值,系统大致包括信号发生部分、数/模转换部分以及液晶显示部分三部分,其中尤其对数/模转换部分和波形产生和变化部分进行详细论述。

关键词:单片机AT89S52、DAC0832、液晶1602目录1. 系统设计1.1 设计要求1.2方案设计与论证1.2.1 信号发生电路方案论证 1.2.2 单片机的选择论证1.2.3 显示方案论证1.2.4 键盘方案论证1.3 总体系统设计1.4 硬件实现及单元电路设计1.4.1 单片机最小系统的设计1.4.2 波形产生模块设计1.4.3 显示模块的设计1.4.4 键盘模块的设计1.5 软件设计流程1.6 源程序2. 输出波形的种类与频率的测试2.1 测试仪器及测试说明2.2 测试结果3、附录3.1 参考文献3.2 附图1、系统设计经过考虑,我们确定方案如下:利用AT89C52单片机采用程序设计方法产生锯齿波、三角波、正弦波、方波四种波形,再通过D/A转换器DAC0832将数字信号转换成模拟信号,滤波放大,最终由示波器显示出来,通过键盘来控制四种波形的类型选择、频率变化,最终输出显示其各自的类型以及数值。

1.1、设计要求1)、利用单片机采用软件设计方法产生四种波形2)、四种波形可通过键盘选择3)、波形频率可调4)、需显示波形的种类及其频率1.2方案设计与论证1.2.1 信号发生电路方案论证方案一:通过单片机控制D/A,输出四种波形。

C8051F350单片机1602液晶显示程序

C8051F350单片机1602液晶显示程序

#include <C8051F350.h>#include <stdio.h>#include <math.h>//-----------------------------------------------------------------------------// 16-bit SFR Definitions for 'F35x//-----------------------------------------------------------------------------sfr16 TMR2RL = 0xCA; // Timer2 reload valuesfr16 TMR2 = 0xCC; // Timer2 countersfr16 ADC0DEC = 0x9A; // ADC0 Decimation Ratio Register//sfr16 ADC0 = 0xbd;//-----------------------------------------------------------------------------// Global CONSTANTS//-----------------------------------------------------------------------------#define SYSCLK 24500000 // SYSCLK frequency in Hz#define MDCLK 2457600 // Modulator clock in Hz (ideal is// (2.4576 MHz)#define OWR 960 // Desired Output Word Rate in Hz ADC0输出字速率,最大960 #define BAUDRATE 115200 // Baud rate of UART in bps#define uchar unsigned char#define uint unsigned int#define DataPort P0sbit LCM_EN=P1^0;sbit LCM_RS=P1^1;unsigned char D1,D2,D3,D4,D5,D6,D7,D8;//sbit LED = P0^7;unsigned int k;//-----------------------------------------------------------------------------// Function PROTOTYPES//-----------------------------------------------------------------------------void Oscillator_Init (void);void Port_Init (void);void UART0_Init (void);void ADC0_Init(void);void delay(int i);void WriteCommandLCM(uchar CMD);void WriteDataLCM(uchar dataW);void InitLcd();void lcd_write_char(uchar x,uchar y,uchar dataW) ;//-----------------------------------------------------------------------------// MAIN Routine//-----------------------------------------------------------------------------void main (void){PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer// enable)Oscillator_Init(); // Initialize system clockPort_Init(); // Initialize Crossbar and GPIO// UART0_Init(); // Initialize UART0 for printf'sInitLcd();ADC0_Init(); // Initialize ADC0AD0INT = 0;ADC0MD = 0x83; // Start continuous conversions EA = 1; // Enable global interruptswhile (1) { // Spin forever}}//-----------------------------------------------------------------------------// Initialization Subroutines//-----------------------------------------------------------------------------void delay(int i) //大概0.43ms{int j,k;for(j=0;j<i;j++)for(k=0;k<2000;k++);}void lcd_write_char(uchar x,uchar y,uchar dataWord) //y是行,x是列,都是从0开始计数{unsigned char add;if(y==0)add=0x80+x;elseadd=0xc0+x;WriteCommandLCM(add);WriteDataLCM(dataWord);}void WriteCommandLCM(uchar CMD){//delay(2);LCM_EN=0;LCM_RS=0;DataPort&=0xf0;// delay(2);DataPort|=(CMD&0xf0)>>4; delay(5);LCM_EN=1;delay(10);LCM_EN=0;delay(10);//CMD=CMD>>4;DataPort&=0xf0;// delay(2);DataPort|=(CMD&0x0f); delay(10);LCM_EN=1;delay(10);LCM_EN=0;}void WriteDataLCM(uchar dataW) // delay(2);LCM_EN=0;LCM_RS=1;// delay(2);DataPort&=0xf0;// delay(2);DataPort|=(dataW&0xf0)>>4; delay(2);LCM_EN=1;delay(5);LCM_EN=0;delay(5);// dataW=dataW>>4;DataPort&=0xf0;// delay(2);DataPort|=(dataW&0x0f);delay(2);LCM_EN=1;delay(5);LCM_EN=0;}void InitLcd(){delay(2000);WriteCommandLCM(0x28); //4位数据总线//delay(5);WriteCommandLCM(0x01); //清屏WriteCommandLCM(0x0C); //显示开及光标设置// WriteCommandLCM(0x0f);// delay(200);}//----------------------------------------------------------------------------- // Oscillator_Init//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// This routine initializes the system clock to use the internal 24.5MHz// oscillator as its clock source. Also enables missing clock detector reset.////-----------------------------------------------------------------------------void Oscillator_Init (void){OSCICN = 0x83; // Configure internal oscillator for 配置内部振荡器// its lowest frequency RSTSRC = 0x04; // Enable missing clock detector}//-----------------------------------------------------------------------------// Port_Init//-----------------------------------------------------------------------------//// Return Value : None// Parameters : None////ThisfunctioninitializestheGPIO and the Crossbar 初始化GPI0和交叉开关//// Pinout://// P0.4 - UART TX (digital, push-pull)// P0.5 - UART RX (digital, open-drain)//// AIN0.2 - ADC0 input////-----------------------------------------------------------------------------void Port_Init (void){// XBR0 = 0x01; // UART0 SelectedXBR1 = 0x40; // Enable crossbar and weak pull-ups P0MDOUT |= 0xDf; // TX, LEDs = Push-pullP1MDOUT |=0x03;}//-----------------------------------------------------------------------------// UART0_Init//-----------------------------------------------------------------------------//// Return Value : None// Parameters : None//// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.////-----------------------------------------------------------------------------/*void delay(unsigned int time){unsigned int i;while(--time){for(i=0;i<125;i++);}}*//*void UART0_Init (void){SCON0 = 0x10; // SCON0: 8-bit variable bit rate 串口控制寄存器// level of STOP bit is ignored// RX enabled// ninth bits are zeros// clear RI0 and TI0 bits if (SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2);CKCON |= 0x08; // T1M = 1; SCA1:0 = xx} else if (SYSCLK/BAUDRATE/2/256 < 4) {TH1 = -(SYSCLK/BAUDRATE/2/4);CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01CKCON |= 0x01;} else if (SYSCLK/BAUDRATE/2/256 < 12) {TH1 = -(SYSCLK/BAUDRATE/2/12);CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00} else if (SYSCLK/BAUDRATE/2/256 < 48) {TH1 = -(SYSCLK/BAUDRATE/2/48);CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10CKCON |= 0x02;} else {while (1); // Error. Unsupported baud rate }TL1 = TH1; // Init Timer1 定时器1是用来确定有相同的波特率TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreloadTMOD |= 0x20;TR1 = 1; // START Timer1TI0 = 1; // Indicate TX0 ready}*///-----------------------------------------------------------------------------// ADC0_Init//-----------------------------------------------------------------------------//// Return Value : None// Parameters : None//// Initialize the ADC to use the temperature sensor. (non-differential)////-----------------------------------------------------------------------------void ADC0_Init (void){REF0CN |= 0x03; // Enable internal VrefADC0CN = 0x00; // Gain = 1, Unipolar mode 最后三位PGA增益=1,ADC控制寄存器ADC0CF = 0x00; // Interrupts upon SINC3 filter output ADC0配置寄存器,位4选择哪一个滤波器转换结束后使AD0INT中断标志置1,// and uses internal VREF 位2是VREF源选择位ADC0CLK = (SYSCLK/MDCLK)-1; // Generate MDCLK for modulator. 调制器时钟分频系数,由最佳调制器时钟频率反求系数// Ideally MDCLK = 2.4576MHz// Program decimation rate for desired OWRADC0DEC = ((unsigned long) MDCLK / (unsigned long) OWR / // ADC0抽取比寄存器,确定ADC输出字速率,由输出字速率反求抽取比(unsigned long) 128) - 1;ADC0BUF = 0x00; // Turn off Input BuffersADC0MUX = 0x08; // Select AIN0.2 模拟多路选择控制寄存器ADC0MD = 0x81; // Start internal calibration ADC0控制寄存器,校准和转换选择while(AD0CALC != 1); // Wait until calibration is completeEIE1 |= 0x08; // Enable ADC0 Interrupts 转换结束中断允许ADC0MD = 0x80; // Enable the ADC0 (IDLE Mode)}//-----------------------------------------------------------------------------// Interrupt Service Routines//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// ADC0_ISR//-----------------------------------------------------------------------------//// This ISR prints the result to the UART. The ISR is called after each ADC // conversion.////-----------------------------------------------------------------------------void ADC0_ISR (void) interrupt 10{unsigned long ADC_OutputVal;static double accumulator = 0;// unsigned long int i;static unsigned int measurements = 0;static unsigned int number=0;// static unsigned long average;static unsigned int flag = 1;unsigned int result=0;while(!AD0INT);AD0INT = 0;// InitLcd();ADC_OutputVal=0x00000000;ADC_OutputVal = ADC0H;ADC_OutputVal <<= 16;ADC_OutputVal += (long)ADC0L + ((long)ADC0M << 8); //ADC_OutputVal=ADC_OutputVal*0.9992+10126; accumulator += ADC_OutputVal;measurements++;if( measurements== 1){number++;if(number==1){result = accumulator / measurements;/*D1=result/10000000+0x30;D2=(result%10000000)/1000000+0x30;D3=(result%1000000)/100000+0x30;D4=(result%100000)/10000+0x30;D5=(result%10000)/1000+0x30;D6=(result%1000)/100+0x30;D7=(result%100)/10+0x30;D8=(result%10)+0x30;*/number=0;/*D1=1;D2=2;D3=3;D4=4;D5=5;D6=6;D7=7;D8=8;*//* HighData=result>>8; // 串口发送数据LowData=result; a[0]=HighData & 0X0F;a[1]=LowData;for(i=0;i<2;i++){SBUF0=a[i];while(TI0==0){};TI0=0;}*/lcd_write_char(0,0,'A'); lcd_write_char(1,0,'D'); lcd_write_char(2,0,'C'); lcd_write_char(3,0,'0'); lcd_write_char(4,0,':'); lcd_write_char(0,1,'A'); lcd_write_char(1,1,'A'); lcd_write_char(2,1,'1'); lcd_write_char(3,1,'2'); lcd_write_char(4,1,'3'); lcd_write_char(5,1,'4'); lcd_write_char(6,1,'5'); lcd_write_char(7,1,'6');lcd_write_char(8,1,'7');lcd_write_char(9,1,'8');lcd_write_char(10,1,'B');lcd_write_char(11,1,'B');delay(1000);if (flag==1){//WriteCommandLCM(0x01);InitLcd();flag=0;}}measurements = 0;accumulator=0;/* if(number==200) //采集的个数受到accumulator的限制{ average=accumulator/number;//average=average*0.9992+10126;a[0] =average>>24;a[1] =average>>16;a[2] =average>>8;a[3] =average;for(i=1;i<4;i++){SBUF0=a[i]; // 发送完成,产生中断,需要软件清零while(TI0==0){};TI0=0;}accumulator=0;number=0;}*/}}//----------------------------------------------------------------------------- // End Of File//-----------------------------------------------------------------------------。

51单片机驱动ADC0832模数转换程序lcd1602显示

51单片机驱动ADC0832模数转换程序lcd1602显示

51单片机驱动ADC0832模数转换程序-lcd1602显示/*这个芯应用不多*/#include ;#define uchar unsigned char#define uint unsigned intuchar Chan0Value,Chan1Value;sbit RS=P1^0; //1602各控制脚sbit RW=P1^1;sbit EN=P1^2;sbit Cs0832= P2^0;//0832各控制脚sbit Clk0832= P3^6;sbit Di0832= P3^7;sbit Do0832= P3^7;void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){int i,j;for(i=0;i;>;i;}for(i=0;i<8;i++)//从低到高取一次数{if(Do0832) Dat2|=0x01<<i;Clk0832=1; //下降沿有效Clk0832=0;}Cs0832=1;Di0832=1;Clk0832=1; //数据读取完成,释放所有数据线if(Dat1==Dat2)return Dat1; //校验两次数相等,输出}/*本程序与其他一般程序最大的不同就是要读两次一次从最高位到最低位,一次从最低位到最高位,两次所读值相等即为正常,可以输出*//******************************LCD1602*********** ***************************//*************************lcd1602程序**************************/void wr_com(unsigned char com)//写指令// { delay1ms(1);RS=0;RW=0;EN=0;P0=com;delay1ms(1);EN=1;delay1ms(1);EN=0;}void wr_dat(unsigned char dat)//写数据// { delay1ms(1);RS=1;RW=0;EN=0;P0=dat;delay1ms(1);EN=1;delay1ms(1);EN=0;}void lcd_init()//初始化设置//{delay1ms(15);wr_com(0x38);delay1ms(5);wr_com(0x80);delay1ms(5);wr_com(0x01);delay1ms(5);wr_com(0x06);delay1ms(5);wr_com(0x0c);delay1ms(5);}void writevalue(uchar add,uchar dat) {wr_com(0x80+add);wr_dat(dat);}void zifuchuan(uchar *ch){while(*ch!=0)wr_dat(*ch++);delay1ms(20);}void main(void){lcd_init();while(1){Chan0Value=GetValue0832(0);delay1ms(100);Chan1Value=GetValue0832(1);wr_com(0x80);zifuchuan(&quot;Chanal 0:&quot;);writevalue(10,Chan0Value/100+0x30);writevalue(11,Chan0Value%100/10+0x30);writevalue(12,Chan0Value%100%10+0x30);wr_com(0x80+0x40);zifuchuan(&quot;Chanal 1:&quot;);writevalue(0x40+10,Chan1Value/100+0x30);writevalue(0x40+11,Chan1Value%100/10+0x30); writevalue(0x40+12,Chan1Value%100%10+0x30); delay1ms(1000);}}/*此程序只为调通ADC0832,没有对电压值进行转换要想得到准确电压值,请把Chan0Value和Chan1Value 的值乘以5再除以255即可。

(完整版)51单片机毕业课程设计波形发生器

(完整版)51单片机毕业课程设计波形发生器

河南理工大学《单片机应用与仿真训练》设计报告多功能信号发生器设计姓名:王彦凯王翱翔专业班级:电仪09-03指导老师:王莉所在学院:电气工程与自动化学院2012年6月25 日摘要本设计是多功能信号发生器,以 AT89S52 单片机为核心,通过按键输入控制输出信号的类型、频率和幅值,采用 DA 转换芯片DAC0832输出相应的波形,同时以LED 显示器进行实时显示信号相关信息。

我们采用 C 语言进行编程,可实现100-1Khz的方波,锯齿波,三角波和正弦波四种波形的产生,且波形的频率、幅值可通过按键调节,并显示在数码管上。

而且,波形的幅值还可通过电位器实现无极调幅,增加了可选幅值范围。

经测试该设计方案线路优化,结构紧凑,性能优越,满足设计要求。

关键字:单片机AT89S52,DAC0832,信号发生器目录第1章概述 (1)1.1选题背景及其意义 (1)1.2 单片机概述 (1)1.3 信号发生器分类 (1)1.4 研究题目及其意义 (2)第2章信号发生器方案设计与选择 (3)2.1 方案的设计与选择 (3)2.2 设计原理简介 (3)2.3 设计功能 (5)第3章主要电路元器件介绍 (6)3.1 AT89S52单片机简介 (6)3.1.1 单片机简介 (6)3.1.2主要性能 (6)3.1.3 管脚功能说明 (7)3.2 DAC0832简介 (8)3.2.1 DAC0832的主要特性参数 (8)3.2.3 DAC0832工作方式 (9)3.3 数码显示管 (10)3.3.1 原理及分类 (10)3.3.2 显示器的工作方式 (10)3.3.3 数码管字型码 (11)第4章单元电路的硬件设计 (12)4.1 硬件原理框图 (12)4.2 单片机 AT89S52 系统的设计 (12)4.3 时钟电路 (13)4.4复位电路 (13)4.5数码管电路 (14)4.6 DAC0832模数转换电路 (15)4.7 LM324运放电路和低通滤波电路 (16)4.8 按键和波形指示LED电路 (17)第5章系统软件设计 (18)5.1软件开发环境简介 (18)5.1.1 Keil uVision4简介 (18)5.1.2 Proteus7.10 简介 (19)5.1.3 Keil 与Proteus 联合调试仿真 (19)5.2主程序 (20)5.3按键处理程序 (21)5.4 数码管输出程序分析 (22)5.5 各种波形产生思路 (22)5.5.1 方波产生思路 (22)5.5.3 三角波产生思路 (23)5.5.4 正弦波产生思路 (23)5.6 仿真的各种波形效果 (23)第6章课程设计体会 (24)参考文献 (25)致谢 (26)附1:源程序代码 (27)1.主程序 (27)2.头文件 (27)附 2:系统原理图 (31)附 3:实物效果图 (32)第1章概述1.1选题背景及其意义信号发生器又称信号源或振荡器,在生产实践和科技领域中有着广泛的应用。

刘文博的论文初稿

刘文博的论文初稿

哈尔滨剑桥学院毕业设计论文题目:基于单片机多功能信号发生器的系统设计学生:刘文博指导教师:李德胜专业:电气工程及其自动化班级:10电气3 班2014年 5 月哈尔滨剑桥学院毕业设计任务书基于单片机的多波形信号发生器摘要信号发生器是一种常用的信号源,广泛地应用于电子电路、自动控制系统和教学实验等领域。

目前使用的信号发生器大部分是函数信号发生器,且特殊波形发生器的价格昂贵。

本设计使用AT89c51单片机和DAC0832,可产生三角波、方波、正弦波,波形的频率可用程序控制改变。

在单片机上加外围器件距阵式键盘,通过键盘控制波形频率的增减以及波形的选择,并用了LCD显示频率大小。

在单片机的输出端口接DAC0832进行D/A 转换,再通过运放进行波形调整,最后输出波形接在示波器上显示。

本设计具有线路简单、结构紧凑、价格低廉、性能优越等优点。

关键词:信号发生器;单片机;DAC0832AbstractSignal-generator is a kind of signal source in common use, broadly applied at the electronics electric circuit, auto control system and teaching experiment etc. Currently used mostly signal generator is function generator, a special waveform generator is very expensive .This design is usage of the AT89s51 single-chip microcomputer and DAC0832, which can generate triangle wave, square wave, sine wave, the period of wave can be controlled by procedure, at outer circle spare part of the microcomputer, plus independence type keyboard , which can control wave’s frequency increase or decrease and the choice of wave-form, at the same time LED display frequency size. The output of the microcompute connect DAC0832 to carry on a DA conversion,again pass operation amplifier to put an end exportation wave-form. This design has advantage of simple circuit, tightly packed structure, cheap price, superior function etc.Key words:signal generator; MCU; DAC083目录摘要 (I)Abstract (II)1绪论 (1)1.1前言 (1)1.2信号发生器的背景与意义 (1)1.3本次设计任务 (2)2信号发生器现状及主控芯片原理 (3)2.1国内研究成果 (3)2.2信号发生器的发展趋势 (4)2.3研究中存在的问题 (4)2.4主控芯片原理 (5)2.4.1单片机的发展及趋势 (5)2.4.2 51系列单片机的主要特点 (6)2.4.3单片机特性及基本电路 (6)2.4.4 DAC0832模块 (9)3总体设计方案及硬件电路设计 (12)3.1系统总体方案设计 (12)3.2元器件选择 (13)3.2.1主控模块选择 (13)3.2.2采样模块及原理 (13)3.3按键电路 (14)3.3.1按键电路的选择 (14)3.3.2按键的确认及防抖处理 (16)3.4显示电路 (17)3.5D/A电路 (17)3.6流压转换电路 (18)3.7单片机与DAC0832的连接 (19)4软件设计 (20)4.1软件的总体设计 (20)4.2波形程序设计 (20)4.2.1正弦波设计 (20)4.2.2三角波程序设计 (21)4.2.3方波程序设计 (21)4.2.4频率改变与波形输出流程图 (21)4.3频率程序设计 (23)4.4键盘扫描程序与处理程序 (23)4.51602显示程序 (23)5系统调试 (25)5.1仿真图 (25)5.2实物图 (26)结论 (28)致谢 (29)参考文献 (30)附录Ⅰ原理图 (31)附录Ⅱ元器件清单 (32)附录Ⅲ源程序清单 (33)基于单片机的多波形信号发生器1绪论1.1前言在科学研究、工程教育及生产实践中,如工业过程控制、教学实验、机械振动试验、动态分析、材料试验、生物医学等领域,常常需要用到低频信号发生器。

液晶显示控制(1602)c语言实例

液晶显示控制(1602)c语言实例

DB1 低4位三态、 双向数据总线 1位
9
DB2 低4位三态、 双向数据总线 2位
10 DB3 低4位三态、 双向数据总线 3位
11 DB4 高4位三态、 双向数据总线 4位
12 DB5 高4位三态、 双向数据总线 5位
13 DB6 高4位三态、 双向数据总线 6位
14 DB7 高4位三态、 双向数据总线 7位 (最高位)(也是busy flag)
4 可视角度
➢大多数光都是从屏幕中垂直射出来的,所以从某一个 较大的角度观看液晶显示器时,便不能看到原本的颜 色,甚至只能看到全白或全黑。为了解决这个问题, 到目前为止有三种比较流行的技术,分别是: TN+FILM、IPS(IN-PLANE -SWITCHING)和 MVA(MULTI-DOMAIN VERTICAL align MENT)。
(8)写指令38H:显示模式设置; (9)写指令08H:显示关闭;
(10)写指令01H:显示清屏; (11)写指令06H:显示光标移动设置; (12)写指令0CH:显示开及光标设置;
2011年春
LCD 1602初始化函数实例
void Initialize_LCD( )
{
Write_LCD_Command(0x38);
4 RS RS为寄存器选择,高电平1时选择数据寄 存器、低电平0时选择指令寄存器。
5 R/W R/W为读写信号线,高电平时进行读操作, 低电平时进行写操作。
6E
E(或EN)端为使能(enable)端,下降沿使 能。
2011年春
引脚 符号
功能说明
7
DB0 低4位三态、 双向数据总线 0位
(最低位)
8
(2)写指令: 输入:RS=L;RW=L; D0~D7=指令码;E=高脉冲

51单片机方波发生器(LCD显示)

51单片机方波发生器(LCD显示)
//实际硬件时打开此语句
LcdEn=0;
return DBPort;
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND0 // Command
#define LCD_DATA1 // Data
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
/*
void LCD_LoadChar(unsigned char user[8], unsigned char place)
{
unsigned char i;
LCD_Write(LCD_COMMAND,0x40|(place*8));
void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示,无光标
{
unsigned char a[5]; char i, j;
a[0]=(t/10000)%10; //取得整数值到数组
a[1]=(t/1000)%10;
a[2]=(t/100)%10;
a[3]=(t/10)%10;
a[4]=(t/1)%10;
for(i=0; i<5; i++) //转成ASCII码

单片机ADC0832液晶显示程序

单片机ADC0832液晶显示程序

//第三个脉冲
for(i=0;i<8;i++) {
clk=1; clk=0; if(dout) {
dat1|=0x80>>i; } } /* for(i=0;i<8;i++) {
clk=1; clk=0; if(dout) {
dat2|=0x01<<i; } } */ cs=1; din=1; clk=0; // if(dat1==dat2) // { return dat1; // }
if(*p=='\0') break; lcd_writedata(*p); p++; } }
//lcd 从第(行,列,字符)开始写
uchar adc0832(uchar channel) { /* uchar i=0;
uchar dat=0;
if(channel==0)channel=2; if(channel==1)channel=3; din=0;cs=1;clk=0; din=1;cs=0;clk=1;
}
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int /*.......引脚的定义得根据自己具体的板子原理图......*/ sbit cs =P1^2; //adc0832 使能端引脚定义 sbit din=P3^3; //adc0832 输入端定义
sbit dout=P3^2;
//adc0832 输出端定义
sbit clk=P1^1; //时钟引脚

51单片机好学1602全过程C语言编程显示很全的哦(同名3209)

51单片机好学1602全过程C语言编程显示很全的哦(同名3209)

教你轻松学51所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符。

目前市面上字符液晶绝大多数是基于HD44780 液晶芯片的,控制原理是完全相同的,因此基于HD44780 写的控制程序可以很方便地应用于市面上大部分的字符型液晶。

1602液晶的正面(绿色背光,黑色字体)1602液晶背面(绿色背光,黑色字体)另一种1602液晶模块,显示屏是蓝色背光白色字体字符型LCD1602 通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义HD44780 内置了DDRAM、CGROM 和CGRAM。

DDRAM 就是显示数据RAM,用来寄存待显示的字符代码。

共80个字节,其地址和屏幕的对应关系如下表:也就是说想要在LCD1602 屏幕的第一行第一列显示一个"A"字,就要向DDRAM 的00H地址写入“ A字的代码就行了。

但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。

那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。

第二行也一样用前16个地址。

对应如下:DDRAM地址与显示位置的对应关系f 1*I*S3H0UH眄H06H07H OSH佃H OAH ABH6CH flDU OEH■Hl!:朝H 41H42H43H44H45H46H i*7H48H却9H4AH却BH毗H却DH ikEH4FH1Ij (事实上我们往DDRAM 里的00H地址处送一个数据,譬如0x31(数字1的代码)并不能显示1出来。

这是一个令初学者很容易出错的地方,原因就是如果你要想在DDRAM的00H地址处显示数据,则必须将00H加上80H,即80H,若要在DDRAM 的01H处显示数据,则必须将01H加上80H即81H。

依次类推。

大家看一下控制指令的的8条:DDRAM地址的设定,即可以明白是怎么样的一回事了)1602 液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如下表所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A'的代码是01000001B(41H ),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”□RQH 中事科砂押曲宇料其贏对昭舂-wraa上表中的字符代码与我们 PC 中的字符代码是基本一致的。

51单片机 液晶显示 串行模数转换ADC0832

51单片机  液晶显示  串行模数转换ADC0832

#include<reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char//#define LCD_DATA P0;sbit DI = P3^4;//定义ADC各口数据;sbit D0 =P3^4;sbit CLK = P3^5;sbit CS = P3^6;sbit LCD_RS= P2^0;//定义LCD引脚sbit LCD_RW= P2^1;sbit LCD_E= P2^2;uchar code DIS[]={"ADC0832-----TEST"};//ADC832 测试;uchar code dsptab[]={'0','1','2','3','4','5','6','7','8','9'};//字符代表码;/*----------------------------------------------------------------------------------延时子程序----------------------------------*/void delay(uint a){ uint b;for(b=0;b<a;b++);}void delay400ms(void)////400ms延时{ uchar a = 5;uint b;while(a--){ b=7269;while(b--);}}/*-----------------------------------------------------------------------------------读状态----------------------------------------*///读状态子程序;有返回值;返回值类型为CHAR型;//读回的状态通过RETURN返回;uchar read_estate(void) //定义有返回值的函数;{ P0=0Xff; //把LCD端口全置1方便读取信号; LCD_RS=0; //RS置0;LCD_RW=1; //RW置1;LCD_E=0; //E端置0;delay(10); //短延时;LCD_E=1; //E端置1;以锁存数据; while(P0&0x80); //检测忙,则一直循环;return(P0); //返回读取的信号;}/*------------------------------------------------------------------------------------ 写数据------------------------------------------*///写数据子程序;无返回值;输入变量I;//I为要写入LCD中的数据;//数据类型CHAR形;void write_data(uchar i) //定义输入变量值I;{read_estate(); //检测忙信号;P0=i; //把I中数据送到LCD数据端;LCD_RS=1; //RS置1;LCD_RW=0; //RW置0;LCD_E=0; //E置0;delay(10); //短延时;LCD_E=1; //E置1;以锁存数据;}/*--------------------------------------------------------------------------------------- 写指令--------------------------------------------*///写指令子程序;无返回值;输入二个变量I和J.//I为要写入LCD的指令;J为判断要不要检测忙.//如果J为0则不判断检测忙;//如果J为1则判断检测忙;void write_dictate(uchar i,j) //定义二个变量;{if(j)read_estate(); //根据需要检测忙;P0=i; //把要写入的数据送到LCD数据端; LCD_RS=0; //RS置0;LCD_RW=0; //RW置0;LCD_E =1; //E端置0;delay(10); //延时;LCD_E =0; //E端置1;以锁存数据;}/*----------------------------------------------------------------------------------读数据--------------------------------------*///读数据子程序;有返回值,返回值类型为CHAR型;/*uchar read_data(void) //定义有返回值的子函数;{LCD_DATA=0Xff; //LCD数据端口置1;LCD_RS=1; //RS置1;LCD_RW=1; //RW置1;LCD_E=0; //E置0;delay(10); //短延时;LCD_E=1; //E置1;以锁存数据;return(LCD_DATA); //返回读取的值;}/*--------------------------------------------------------------------------------------- LCD初始化-----------------------------------------*///LCD初始化程序;主要作用初始化LCD,对LCD进行复位以及设置;void initialization(void) //定义函数;{delay(50); //延时5MS;write_dictate(0x38,0); //写指令38H;不检测忙;delay(50); //延时5MS;write_dictate(0x38,0); //写指令38H;不检测忙;delay(50); //延时5MS;write_dictate(0x38,0); //写指令38H;不检测忙;delay(50);write_dictate(0x38,1); //显示模式设置;检测忙;write_dictate(0x08,1); //关闭显示;检测忙;write_dictate(0x01,1); //显示清屏;检测忙;write_dictate(0x06,1); //显示光标移动设置;检测忙;write_dictate(0x0C,1); //显示开及光标设置;检测忙;}/*----------------------------------------------------------------------------------在指定位置显示一个字符----------------------*/void displayonechar(uchar x, y,ddata){y &= 0x01;x &= 0x0f; //限制X不能大于15,Y不能大于1 if (y) x+= 0x40; //当要显示第二行时地址码+0x40;x+= 0x80; //算出指令码write_dictate(x,0); //这里不检测忙信号,发送地址码write_data(ddata);}/*----------------------------------------------------------------------------------在指定位置显示一串字符----------------------*/void displaylistchar(uchar x,y,uchar code *ddata){uchar a=0;y&=0x01;x&=0xf;while(ddata[a]>0x20){ if(x<=0xff){displayonechar(x, y,ddata[a]);a++;x++;}}}/*----------------------------------------------------------------------------------读ADC0832的数据----------------------------------*/ unsigned char readadc(void){ unsigned char dat,i;CLK=0; //芯片复位CS=1;_nop_();CS=0;_nop_();DI=1; //启动位CLK=1;_nop_();CLK=0;DI=1; //配置位1CLK=1;_nop_();CLK=0;DI=0; //配置位2CLK=1;_nop_();CLK=0; //空闲位_nop_();CLK=1;DI=1;for(i=0;i<=8;i++){ //读出8字节数据dat=dat<<1;_nop_();CLK=1;//这里要先1后0...如果是先0后1则输出结果错误...if(DI){dat|=0x01;}_nop_();CLK=0;}CS=1;//关闭芯片return(dat);//返回数据}void main(){ uint dat;delay400ms();//延时400MSinitialization();//LCD复位;displaylistchar(0,0,DIS);//显示ADC832 测试;displayonechar(0,1,'O'); //在LCD是显示OUT:_.___Vdisplayonechar(1,1,'U');displayonechar(2,1,'T');displayonechar(3,1,':');displayonechar(5,1,'.');displayonechar(8,1,'V');while(1)//无限循环...一直读出电压值显示在LCD上;{ displayonechar(13,1,dsptab[readadc()/100]);displayonechar(14,1,dsptab[(readadc()%100)/10]);displayonechar(15,1,dsptab[readadc()%10]);//在LCD最右边显示255中的某一个数据;dat=readadc()/0.542;//0.542是255除以基准电压也就是ADC0832的VCC...得出来了...这个值可能每个人不同.displayonechar(4,1,dsptab[dat/100]);//下面三行显示电压...displayonechar(6,1,dsptab[(dat%100)/10]);displayonechar(7,1,dsptab[dat%10]);delay400ms();//延时400MS}}。

51单片机经典C程序(1602)

51单片机经典C程序(1602)

unsigned char temp; Mcu_init(); while(1) { AT24C02_write(0x00,count[1]); temp=AT24C02_read(0x00); LCD_write_string(0x00,LINE1,"AT24C02 TEST"); LCD_write_char(0x0e,LINE1,(temp/10)|0x30); LCD_write_char(0x0f,LINE1,(temp%10)|0x30); LCD_write_string(0x00,LINE2,"TIMER0 JISHU"); LCD_write_char(0x0e,1,(count[1]/10)|0x30); LCD_write_char(0x0f,1,(count[1]%10)|0x30); AT24C02_write(0x00,count[1]); }
00阅读全文编辑at24c02语言驱动程序lcd160Байду номын сангаас显示zl0801发表于20058259
AT24C02 C语言驱动程序—LCD1602 显示
程序匠人 发表于 2006-4-5 22:31:00 阅读全文 | 回复(1) | 引用通告 AT24C02 C语言驱动程序—LCD1602 显示 -|zl0801 发表于 2005-8-25 9:21:00 //AT24C02 EEPROM drive program //for 51 mcu with lcd1602 as display //designed by zhaoliang //2005-6-14 21:02 #i nclude " reg51.h " #i nclude " intrins.h " /********************************************************************/ //lcd part #define LINE1 0 #define LINE2 1 #define LINE1_HEAD 0x80 #define LINE2_HEAD 0xC0 #define LCD_DELAY_TIME 40 #define DATA_MODE 0x38 #define OPEN_SCREEN 0x0C #define DISPLAY_ADDRESS 0x80 #define CLEARSCREEN LCD_en_command(0x01) //common part #define HIGH 1 #define LOW 0 #define TRUE 1 #define ZERO 0 //at24c02 part #define WRITE24C02 0xA0 #define READ24C02 0xA1 //I2C part #define ACK 0 #define NO_ACK 1 #define MSB 0x80 /********************************************************************/ //change this part at different board

51单片机好学1602全过程C语言编程显示很全的哦

51单片机好学1602全过程C语言编程显示很全的哦

51单片机好学1602全过程C语言编程显示很全的哦阿拉教你轻松学51系列(作者:就抽精品)发布: 2010-2-05 16:03 | 作者: tiankai | 来源: 电子园51单片机学习网阿拉教你轻松学51--------液晶篇(1602)写在开始:(借此灌下水^_^ ) 之前,发了一个帖子,大意是看见杀手和水剑写的帖子,心里也痒痒了,想写一写以前学习单片机过程中的一些经历,希望能给大家一点参考。

无奈最近时间很是紧张,因此,一直都没能着手整理。

本打算星期六写的,但是接到一个朋友的电话,说想买CPLD的开发板。

于是,计划被迫打乱,只好先陪他去电子市场买板子。

回来之后,虽然头很晕(坐车的原因),但是不能再拖了,否则留给大家一个只说不做的印象就不好了。

虽然头晕,但是下面的写出来的东西可不晕。

OK,LET’S GO !1602字符液晶在实际的产品中运用的也比较多了,前几天留意了一下,发现宿舍门前的自动售水机就是采用的1602液晶进行显示的。

而且对于单片机的学习而言,掌握1602的用法是每一个学习者必然要经历的过程。

在此,我将使用1602过程中遇到的问题以及感受记录下来,希望能够给初学者带来一点指导,少走一点弯路。

所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符。

目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。

1602液晶的正面(绿色背光,黑色字体)1602液晶背面(绿色背光,黑色字体)另一种1602液晶模块,显示屏是蓝色背光白色字体字符型LCD1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义如下表所示:HD44780内置了DDRAM、CGROM 和CGRAM。

DDRAM就是显示数据RAM,用来寄存待显示的字符代码。

基于单片机和dac0832的波形发生器

基于单片机和dac0832的波形发生器

基于单片机和dac0832的波形发生器仿真电路图(输出正弦波、三角波,锯齿波)主程序:#include<reg52.h>sbit key2=P2^2;sbit key1=P2^1;sbit key0=P2^0;char flag; //波型输出标置变量bit time;unsigned char i;void frequency() ;void delay(int z) //延时 z毫秒{int x,y;for(x=z;x>0;x--)for(y=124;y>0;y--);}unsigned char sin(unsigned char x)//正弦波{unsigned char code sin_tab[]={0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9c, 0x9f, 0xa2,0xa5, 0xa8, 0xab, 0xae, //上半周0xb0, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc1, 0xc4, 0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3,0xd5, 0xd8,0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xed, 0xef, 0xf0, 0xf2,0xf3, 0xf4,0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,0xf7,0xf6, 0xf4, 0xf3, 0xf2, 0xf0, 0xef, 0xed, 0xec, 0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdc,0xda, 0xd8, 0xd5, 0xd3, 0xd1, 0xce, 0xcc, 0xc9, 0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9,0xb6, 0xb3,0xb0, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c, 0x99, 0x96, 0x92, 0x8f, 0x8c, 0x89,0x86, 0x83, 0x80,0x80, 0x7d, 0x7a, 0x76, 0x73, 0x70, 0x6d, 0x6a, 0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52, //下半周期0x4f, 0x4c, 0x49, 0x46, 0x43, 0x41, 0x3e, 0x3b, 0x39, 0x36, 0x33, 0x31, 0x2e, 0x2c,0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x14, 0x12, 0x10, 0x0f, 0x0d, 0x0c, 0x0b,0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ,0x09, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x23, 0x25, 0x27, 0x2a, 0x2c,0x2e, 0x30, 0x33, 0x35, 0x38, 0x3b, 0x3d, 0x3e, 0x40, 0x43, 0x46, 0x48, 0x4b, 0x4e, 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x5f, 0x60, 0x63, 0x66, 0x69, 0x6b, 0x6d, 0x6f, 0x72, 0x74, 0x76, 0x78, 0x7a,0x7e, 0x80};return sin_tab[x];}void DAC0832(unsigned char x){P1=x;}void main(){char d;d=1;TMOD=0X02;num=10;TH0=256-num; //num用来控制采样一个点所用的时间TL0=256-num;ET0=1; //按键接于外部中断0,与中断1EA=1;TR0=1;flag=2; //开始时有输出i=0;while(1){if(key2==0) //按一下key3,d自加1{delay(5);if(key2==0){while(!key2);d++;if(d==21)//当d=21,d变为1d=1;}}frequency() ;if(time==1){time=0;if(i>255)i=0;elsei=i+d; //设置采样间隔switch(flag) //当按键1的为输出三角波,按键2时输出正弦波{case 0:DAC0832(i);break;// 当flag=0时,锯齿波case 1:if(i>127)// 当flag=1时,三角波DAC0832(255-i);elseDAC0832(i);break;case 2: DAC0832(sin(i)); //当flag=2时,正弦波break;default: break;}}}}void time0() interrupt 1{TH0=256-num;TL0=256-num;time=1;}void frequency(){if(key0==0) // //key0控制flag,频率选择{delay(5) ;if(key0==0) //再次检测{while(!key0); //等待按键释放flag++; //按一下加1if(flag==3) //大于2返回0flag=0;}}if(key1==0) //检测P21是否按下{delay(5) ;if(key1==0) //再次检测{while(!key1);num=num+10; //按一下减10 if(num==250) //小于5,返回5num=10;}}}。

基于51单片机和DAC0832的信号源(proteus电路图加程序)

基于51单片机和DAC0832的信号源(proteus电路图加程序)

基于51单⽚机和DAC0832的信号源(proteus电路图加程序)班级学号⾃动测试实验报告学院机电⼯程学院专业测控技术与仪器导师姓名吕晓洲学⽣姓名学号摘要本⽂介绍了以8051和DAC0832为核⼼的信号源,可以通过按键选择正弦波、⽅波、三⾓波、锯齿波和梯形波,也可以通过按键选择798.6Hz、266.2Hz、88.7Hz、29.6Hz、9.85Hz、3.3Hz、1.1Hz共九档频率。

波形和频率通过软件改变,幅值通过硬件放⼤的放⼤器改变。

本信号源具有结构简单、功能丰富、使⽤⽅便另外价格实惠等特点。

【关键词】单⽚机,8051,DAC0832,信号源,频率,波形⼀.实验要求以及⽅案选择1.实验要求:设计⼀个信号源,能产⽣正弦波、三⾓波、锯齿波、⽅波等简单的波形,能够⽅便改变波形和频率。

2.⽅案选择:⽅案⼀:完全由硬件电路制作,使⽤传统的锁相频率合成⽅法。

通过芯⽚IC145152,压控振荡器搭接的锁相环电路输出稳定性极好的正弦波,再利⽤过零⽐较器转换成⽅波,积分电路转换成三⾓波。

此⽅案,电路复杂,⼲扰因素多,不易实现。

⽅案⼆:直接利⽤波形产⽣芯⽚,例如,利⽤MAX038芯⽚组成的电路输出波形。

MAX038是精密⾼频波形产⽣电路,能够产⽣准确的锯齿波、三⾓波、⽅波和正弦波四种周期性波形。

但此⽅案成本⾼,程序复杂度⾼。

⽅案三:通过单⽚机控制DAC,输出五种波形。

此⽅案输出的波形分辨率不够⾼,频率有限。

但此⽅案电路简单、成本低,波1.80C51单⽚机80C51单⽚机属于MCS-51系列单⽚机,由Intel公司开发,其结构是8048的延伸,改进了8048的缺点,增加了如乘(MUL)、除(DIV)、减(SUBB)、⽐较(CMP)、16位数据指针、布尔代数运算等指令,以及串⾏通信能⼒和5个中断源。

采⽤40引脚双列直插式DIP(Dual In Line Package),内有128个RAM单元及4K的ROM。

它把构成计算机的中央处理器CPU、存储器、寄存器、I/O接⼝制作在⼀块集成电路芯⽚中,从⽽构成较为完整的计算机、⽽且其价格便宜。

51单片机驱动LCD1602程序设计(C语言)

51单片机驱动LCD1602程序设计(C语言)

4.显示开关控制指令
功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁。参数设定的情况如下: 位名 D C B 设置 0=显示功能关 0=无光标 0=光标闪烁 1=显示功能开 1=有光标 1=光标不闪烁
5.设定显示屏或光标移动方向指令
功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下: S/C 0 0 1 1 0 1 0 1 R/L 设定情况 光标左移 1 格,且 AC 值减 1 光标右移 1 格,且 AC 值加 1 显示器上字符全部左移一格,但光标不动 显示器上字符全部右移一格,但光标不动
10.数据写入 DDRAM 或 CGRAM 指令一览
功能:<1> 将字符码写入 DDRAM,以使液晶显示屏显示出相对应的字符; <2> 将使用者自己设计的图形存入 CGRAM。
11.从 CGRAM 或 DDRAM 读出数据的指令一览
功能:读取 DDRAM 或 CGRAM 中的内容。
基本操作时序:
读状态
从上图可以看出,“A”字的对应上面高位代码为 0100,对应左边低位代码为 0001,合起来就 是 01000001,也就是 41H。可见它的代码与我们 PC 中的字符代码是基本一致的。因此我们在向 DDRAM 写 C51 字符代码程序时甚至可以直接用 P1='A'这样的方法。 PC 在编译时就把“A”先转为 41H 代码了。 字符代码 0x00~0x0F 为用户自定义的字符图形 RAM(对于 5X8 点阵的字符,可以存放 8 组, 5X10 点阵的字符,存放 4 组),就是 CGRAM 了。后面我会详细说的。 0x20~0x7F 为标准的 ASCII 码, 0xA0~0xFF 为日文字符和希腊文字符, 其余字符码(0x10~ 0x1F 及 0x80~0x9F)没有定义。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

显示频率,幅度可调,可产生四种波形,正弦波,方波,锯齿波,三角波,希望你能喜欢,给你发了一张效果图,喜欢的话别忘了采纳我的回答啊#include<>#define uchar unsigned char#define uint unsigned int#define DAdata P0 //DA数据端口sbit DA_S1= P2^0; // 控制DAC0832的8位输入寄存器,仅当都为0时,可以输出数据(处于直通状态),否则,输出将被锁存sbit DA_S2= P2^1; // 控制DAC0832的8位DAC寄存器,仅当都为0时,可以输出数据(处于直通状态),否则,输出将被锁存sbit key= P3^2;uchar wavecount; //'抽点'计数uchar THtemp,TLtemp;//传递频率的中间变量uchar judge=1; //在方波输出函数中用于简单判别作用uchar waveform; //当其为0、1、2时,分别代表三种波uchar code freq_unit[3]={10,50,200}; //三种波的频率单位uchar idata wavefreq[3]={1,1,1}; //给每种波定义一个数组单元,用于存放单位频率的个数uchar code lcd_hang1[]={"Sine Wave " "Triangle Wave " "Square Wave " "Select Wave: " "press key! "};uchar idata lcd_hang2[16]={"f= Hz "};uchar code waveTH[]={0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xec,0xf6,0xf9,0xfb,0xfc,0xfc,0xfd,0xfd,0xfd,0xfe};uchar code waveTL[]={0x06,0x8a,0x10,0x4e,0x78,0x93,0xa8,0xb3,0xbe,0xc6, //正弦波频率调整中间值0xac,0xde,0x48,0x7a,0x99,0xaf,0xbb,0xc8,0xd0,0xde, //三角波频率调整中间值0x88,0x50,0x90,0x32,0x34,0xbe,0x4a,0xa3,0xe5,0x2c};/******************************************************************** *****************************/uchar code triangle_tab[]={ //每隔数字8,采取一次0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68 ,0x70,0x78,0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8, 0xf0,0xf8,0xff,0xf8,0xf0,0xe8,0xe0,0xd8,0xd0,0xc8,0xc0,0xb8,0xb0,0xa8,0xa0,0x98,0x90,0 x88,0x80,0x78,0x70,0x68,0x60,0x58,0x50,0x48,0x40,0x38,0x30,0x28,0x20,0x18,0x10 ,0x08,0x00};uchar code sine_tab[256]={//输出电压从0到最大值(正弦波1/4部分)0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,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,0x e1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0 xfe,0xff,0xff,0xff,0xff,0xff,0xff,//输出电压从最大值到0(正弦波1/4部分)0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6, 0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,0xd4, 0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99 , 0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,//输出电压从0到最小值(正弦波1/4部分)0x80,0x7c,0x79,0x76,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,0x00,0x00,0x00,0x00,0x00,//输出电压从最小值到0(正弦波1/4部分)0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x0 7,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,0x72,0x76,0x79,0x7c,0x80};void delay(uchar z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void triangle_out() //三角波输出{DAdata=triangle_tab[wavecount++];if(wavecount>64) wavecount=0;DA_S1=0; //打开8位输入寄存器DA_S1=1; //关闭8位输入寄存器void sine_out() //正弦波输出{DAdata=sine_tab[wavecount++];DA_S1=0; //打开8位输入寄存器DA_S1=1; //关闭8位输入寄存器}void square_out() //方波输出{judge=~judge;if(judge==1) DAdata=0xff;else DAdata=0x00;DA_S1=0; //打开8位输入寄存器DA_S1=1; //关闭8位输入寄存器}/************1602液晶的相关函数*************/#define lcd_ports P1sbit rs=P2^2;sbit rw=P2^3;sbit lcden=P2^4;void write_com(uchar com){rs=0; //置零,表示写指令lcden=0;lcd_ports=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date){rs=1; //置1,表示写数据(在指令所指的地方写数据)lcden=0;lcd_ports=date;delay(5);lcden=1;delay(5);lcden=0;void disp_lcd(uchar addr,uchar *temp1){uchar num;write_com(addr);delay(1); //延时一会儿for(num=0;num<16;num++){write_date(temp1[num]);//或者这样写write_date(*(temp1+num));delay(1);}}void init_lcd(){//uchar num;lcden=0; //可有可无rw=0; //初始化一定要设置为零,表示写数据write_com(0x38); //使液晶显示点阵,为下面做准备write_com(0x0c); //初始设置write_com(0x06); //初始设置write_com(0x01); //清零write_com(0x80); //使指针指向第一行第一格disp_lcd(0x80,&lcd_hang1[3*16]); //在第一行显示disp_lcd(0xc0,&lcd_hang1[4*16]); //在第二行显示}/********************1602液晶函数声明结束*********************/ void main(){uchar i=0;DA_S2=0; //使DAC寄存器处于直通状态DAdata=0;DA_S1=1; //关闭8位输入寄存器init_lcd();waveform=0;TMOD=0x01; //设置定时器0为16位工作方式IT0=1; //设置外部中断0为下降沿触发ET0=1; //开定时器中断EX0=1;EA=1;while(1){//DAout(0xff); //可输出TTL波形//DAout(0x80);//T_temp=32;}}void timer0() interrupt 1{TH0=THtemp;TL0=TLtemp;if(waveform==0) sine_out();else if(waveform==1) triangle_out();else if(waveform==2) square_out();}void key_int0() interrupt 0{uchar keytemp;uint total_freq; //总频率EA=0; TR0=0; //关总中断与定时器delay(5); //延时够吗if(key==0) //确实有按键按下而引发中断{keytemp=P3&0xf0; //获取P3口高四位的值switch(keytemp){case 0xe0: //选择波形waveform++;if(waveform>2) waveform=0;break;case 0xd0: //频率按规定单位依次增加wavefreq[waveform]++;if(wavefreq[waveform]>10) wavefreq[waveform]=1; // /*这边要用“>10”,因为它比“=11”可靠break;case 0xb0: //频率按规定单位依次衰减wavefreq[waveform]--;if(wavefreq[waveform]<1) wavefreq[waveform]=10; //这边要用“<1”,因为它比“=0”可靠性更高break;case 0x70: //TTL输出DA_S2=1; //使DAC寄存器关闭break;}THtemp=waveTH[waveform*10+(wavefreq[waveform]-1)]; //方括号中选取第几个数后,并把该值赋给T_tempTLtemp=waveTL[waveform*10+(wavefreq[waveform]-1)];total_freq= wavefreq[waveform] * freq_unit[waveform]; //求输出频率(个数*单位)lcd_hang2[5]=total_freq%10+0x30; //在液晶中显示个位,(0x30 在液晶显示中表示数字0)total_freq/=10; lcd_hang2[4]=total_freq%10+0x30; //在液晶中显示时十位total_freq/=10; lcd_hang2[3]=total_freq%10+0x30; //在液晶中显示时百位total_freq/=10; lcd_hang2[2]=total_freq%10+0x30; //在液晶中显示时千位disp_lcd(0x80,&lcd_hang1[waveform*16]); //在第一行显示disp_lcd(0xc0,lcd_hang2); //在第二行显示}wavecount=0; //'抽点'计数清零while(!key);EA=1; TR0=1; //开启总中断与定时器}。

相关文档
最新文档