//STC 单片机内部ADC转换程序//可选择查询和中断方式//H文件#ifndef __ADC_H__#define __ADC_H__#define ADC_POWER 0x80 //ADC 电源控制位#define ADC_FLAG 0x10 //ADC 完成标志#define ADC_START 0x08 //ADC 启动控制位//ADC转换速度选择#define ADC_SPEEDLL 0x00 //420 clocks#define ADC_SPEEDL 0x20 //280 clocks#define ADC_SPEEDH 0x40 //140 clocks#define ADC_SPEEDHH 0x60 //70 clocksunsigned int AD_Result_Temp;unsigned int GetADCResult (unsigned char chan); //ADC 转换处理,查询方式#endif//C文件#ifndef __ADC_C__#define __ADC_C__#include <adc.h>//#include <cbit.h>/*----------------------------初始化ADC 寄存器中断方式----------------------------void InitADC(){unsigned unsigned char chan=0;P1ASF = 0xff; //设置P1口全部为ADC通道ADC_RES = 0; //清除高8位缓冲数据ADC_RESL = 0; //清除低2位缓冲数据ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | chan;_nop_();_nop_(); //打开ADC}*///----------------------------//ADC 中断处理//----------------------------/*void adc_isr() interrupt 5 using 1{unsigned unsigned int AD_Result_TempADC_CONTR &= !ADC_FLAG; //清除ADC 中断标志位return (((AD_Result_Temp|ADC_RES)<<2)+ADC_RESL); //返回10位ADC转换结果if (++ch > 7) ch = 0; //却换到下一个通道ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | chan;}*/unsigned int GetADCResult(unsigned char chan){AD_Result_Temp=0;ADC_RES=0;ADC_RESL=0;ADC_CONTR = ADC_POWER | ADC_SPEEDHH | chan | ADC_START;_nop_(); //Must wait before inquiry_nop_();_nop_();_nop_();while (!(ADC_CONTR & ADC_FLAG));//等待完成ADC_CONTR &= ~ADC_FLAG; //关闭ADC转换AD_Result_Temp=(((AD_Result_Temp|ADC_RES)<<2)+ADC_RESL);return AD_Result_Temp;}#endif//74HC595//发送完一个8位数据,就锁存一次// 8个数码管,可以这样做// for(i=0;i<8;i++)// {// Send_HC595(....//要发送的8为数据);// Show_595();// }/********************************************************//* *//*将显示数据送入74HC595内部移位寄存器*//* *//********************************************************/void Send_HC595(INT16U LED_DATA){INT8U i;for(i=0;i<8;i++){HC595_DS=LED_DATA&0x80;HC595_SHCP=1; //上升沿发生移位_nop_();_nop_();HC595_SHCP=0;LED_DATA=LED_DATA<<1;}}/********************************************************//* *//*将移位寄存器内的数据锁存到输出寄存器并显示*//* *//********************************************************/void Show_595(void){HC595_STCP=0;_nop_();_nop_();HC595_STCP=1; //上升沿将数据送到输出锁存器_nop_();_nop_();HC595_STCP=0;}//74HC164#ifndef __74LS164_H__#define __74LS164_H__extern void Write_Bit8(unsigned char bit_8){unsigned char i;for(i=8;i>0;i--) //数码管段8位数据{Data=bit_8&0x80; //传送一位数据CLK=0;CLK=1;bit_8=bit_8<<1;}}#endif20位串口A/D转换器CS5513 20位串口A/D转换器CS5513 接口程序2010-03-22 14:56//cs5513接口的C51官方程序//cs5513返回长整型数据//CS=0时表示片选有效,当然可以直接接地,这样可以节省一个I/O口sbit ADCS=P2^0;sbit ADCLK=P2^1;sbit ADDO=P2^2;unsigned long int ADConv(void){uchar i;unsigned long int Result=0;ADCLK=0;ADCS=0;_nop_();_nop_();_nop_();ADCLK=0;while(ADDO);ADCLK=1;_nop_();for(i=0;i<3;i++){ADCLK=0;_nop_();ADCLK=1;}for (i=0;i<20;i++){ADCLK=0;Result=Result<<1;if (ADDO)Result=Result+1;ADCLK=1;}ADCS=1;return Result;}//LCD SMC12864-05#ifndef _CRYFUCNS_H_#define _CRYFUCNS_H_void Send(unsigned char type,unsigned char transdata);void Init_LCD(void);void Clear_GDRAM(void);void Disp_HZ(unsigned char addr,const unsigned char * pt,unsigned char num); void Draw_PM(const unsigned char *ptr);void Draw_TX(unsigned char Yaddr,unsigned char Xaddr,const unsigned char * dp) ; void Disp_SZ(unsigned char addr,unsigned char shuzi);#endif#include <cryfucns.h>#include <STC12C5A.H>#include<intrins.h>#include <types.h>extern const INT8U shuzi_table[];void Send(INT8U type,INT8U transdata);/**********液晶控制IO的宏定义*************/sbit RS_CS = P0^0;sbit RW_SDI = P0^1;sbit E_CLK = P0^2;/*******************************************函数名称:delay_Nus功能:延时N个us的时间参数:n--延时长度返回值:无********************************************/void delay_Nus(INT16U n){INT8U i;for(i = n;i > 0;i--)_nop_();}/*******************************************函数名称:delay_1ms功能:延时约1ms的时间参数:无返回值:无********************************************/void delay_1ms(void){INT8U i;for(i = 150;i > 0;i--) _nop_();}/*******************************************函数名称:delay_Nms功能:延时N个ms的时间参数:无返回值:无********************************************/void delay_Nms(INT16U n){INT16U i = 0;for(i = n;i > 0;i--)delay_1ms();}/*******************************************函数名称:Ini_Lcd功能:初始化液晶模块参数:无返回值:无********************************************/void Init_LCD(void){delay_Nms(100); //延时等待液晶完成复位Send(0,0x30); /*功能设置:一次送8位数据,基本指令集*/delay_Nus(72);Send(0,0x02); /*DDRAM地址归位*/delay_Nus(72);Send(0,0x0c); /*显示设定:开显示,不显示光标,不做当前显示位反白闪动*/delay_Nus(72);Send(0,0x01); /*清屏,将DDRAM的位址计数器调整为“00H”*/delay_Nus(72);Send(0,0x06); /*功能设置,点设定:显示字符/光标从左到右移位,DDRAM地址加1*/ delay_Nus(72);}/*******************************************函数名称:Send功能:MCU向液晶模块发送1一个字节的数据参数:type--数据类型,0--控制命令,1--显示数据transdata--发送的数据返回值:无********************************************/void Send(INT8U type,INT8U transdata){INT8U firstbyte = 0xf8;INT8U temp;INT8U i,j = 3;if(type) firstbyte |= 0x02;RS_CS=1;E_CLK=0;while(j > 0){if(j == 3) temp = firstbyte;else if(j == 2) temp = transdata&0xf0;else temp = (transdata << 4) & 0xf0;for(i = 8;i > 0;i--){if(temp & 0x80) RW_SDI=1;else RW_SDI=0;E_CLK=1;temp <<= 1;E_CLK=0;}//三个字节之间一定要有足够的延时,否则易出现时序问题if(j == 3) delay_Nus(600);else delay_Nus(200);j--;}RW_SDI=0;RS_CS=0;}/*******************************************函数名称:Clear_GDRAM功能:清除液晶GDRAM内部的随机数据参数:无返回值:无********************************************/void Clear_GDRAM(void){INT8U i,j,k;Send(0,0x34); //打开扩展指令集i = 0x80;for(j = 0;j < 32;j++){Send(0,i++);Send(0,0x80);for(k = 0;k < 16;k++){Send(1,0x00);}}i = 0x80;for(j = 0;j < 32;j++){Send(0,i++);Send(0,0x88);for(k = 0;k < 16;k++){Send(1,0x00);}}Send(0,0x30); //回到基本指令集}/*******************************************函数名称:Disp_HZ功能:显示汉字程序参数:addr--显示位置的首地址pt--指向显示数据的指针num--显示数据的个数返回值:无********************************************/ void Disp_HZ(INT8U addr,const INT8U * pt,INT8U num) {INT8U i;Send(0,addr);for(i = 0;i < (num*2);i++)Send(1,*(pt++));}/*******************************************函数名称:Draw_PM功能:在整个屏幕上画一个图片参数:ptr--指向保存图片位置的指针返回值:无********************************************/ void Draw_PM(const INT8U *ptr){INT8U i,j,k;Send(0,0x34); //打开扩展指令集i = 0x80;for(j = 0;j < 32;j++){Send(0,i++);Send(0,0x80);for(k = 0;k < 16;k++){Send(1,*ptr++);}}i = 0x80;for(j = 0;j < 32;j++){Send(0,i++);Send(0,0x88);for(k = 0;k < 16;k++){Send(1,*ptr++);}}Send(0,0x36); //打开绘图显示Send(0,0x30); //回到基本指令集}/*******************************************函数名称:Draw_TX功能:在液晶上描绘一个16*16的图形参数:Yaddr--Y地址,Xaddr--X地址dp--指向保存图形数据的指针返回值:无********************************************/void Draw_TX(INT8U Yaddr,INT8U Xaddr,const INT8U * dp){INT8U j;INT8U k = 0;Send(0,0x34); //使用扩展指令集,关闭绘图显示for(j = 0;j < 16;j++){Send(0,Yaddr++); //Y地址Send(0,Xaddr); //X地址Send(1,dp[k++]); //送两个字节的显示数据Send(1,dp[k++]);}Send(0,0x36); //打开绘图显示Send(0,0x30); //回到基本指令集模式}/*******************************************函数名称:Disp_SZ功能:显示一个两位数字参数:addr--显示地址数字--显示的数字返回值:无********************************************/void Disp_SZ(INT8U addr,INT8U shuzi){INT8U tmp0,tmp1;tmp0 = shuzi / 10;tmp1 = shuzi % 10;Send(0,addr);Send(1,shuzi_table[tmp0]);Send(1,shuzi_table[tmp1]);}//STC 内部EEPROM 操作程序#ifndef _EEPROM_H_#define _EEPROM_H_//定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数//#define ENABLE_ISP 0x80 //系统工作时钟<30MHz 时,对IAP_CONTR 寄存器设置此值//#define ENABLE_ISP 0x81 //系统工作时钟<24MHz 时,对IAP_CONTR 寄存器设置此值//#define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值#define ENABLE_ISP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值//#define ENABLE_ISP 0x84 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值//#define ENABLE_ISP 0x85 //系统工作时钟<3MHz 时,对IAP_CONTR 寄存器设置此值//#define ENABLE_ISP 0x86 //系统工作时钟<2MHz 时,对IAP_CONTR 寄存器设置此值//#define ENABLE_ISP 0x87 //系统工作时钟<1MHz 时,对IAP_CONTR 寄存器设置此值#define FIRST 0x0000#define SECOND 0x200#define THIRD 0x400#define START_FLAG 0xE1union eeprom_addr{unsigned int temp16;unsigned char temp8[2];}addr16;void IAP_Disable (void); //关闭IAP 功能void Sector_Erase (unsigned int add); //擦除扇区void Byte_Program (unsigned int add, unsigned char ch); //字节编程,调用前需打开IAP 功能extern unsigned char Byte_Read (unsigned int add); //读一字节,调用前需打开IAP 功能#endif#include <eeprom.h>/*********************************************************************************************** 读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节************************************************************************************************ /unsigned char Byte_Read(unsigned int add){EA = 0;IAP_DATA = 0x00;IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间IAP_CMD = 0x01; //IAP/ISP/EEPROM 字节读命令addr16.temp16 = add;IAP_ADDRH = addr16.temp8[0]; //设置目标单元地址的高8 位地址IAP_ADDRL = addr16.temp8[1]; //设置目标单元地址的低8 位地址IAP_TRIG = 0x5A; //先送5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动_nop_();IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关EA = 1;return (IAP_DATA);}/*********************************************************************************************** *****字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据************************************************************************************************ *****/void Byte_Program(unsigned int add, unsigned char ch){EA = 0;IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash操作等待时间IAP_CMD = 0x02; //IAP/ISP/EEPROM 字节编程命令addr16.temp16 = add;IAP_ADDRH = addr16.temp8[0]; //设置目标单元地址的高8 位地址IAP_ADDRL = addr16.temp8[1]; //设置目标单元地址的低8 位地址IAP_DATA = ch; //要编程的数据先送进IAP_DATA 寄存器IAP_TRIG = 0x5A; //先送5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动_nop_();IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,EA = 1; //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关}/*********************************************************************************************** *******擦除扇区, 入口:DPTR = 扇区地址************************************************************************************************ *******/void Sector_Erase(unsigned int add){EA = 0;IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间IAP_CMD = 0x03; //IAP/ISP/EEPROM 扇区擦除命令addr16.temp16 = add;IAP_ADDRH = addr16.temp8[0]; //设置目标单元地址的高8 位地址IAP_ADDRL = addr16.temp8[1]; //设置目标单元地址的低8 位地址IAP_TRIG = 0x5A; //先送5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动_nop_();IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,EA = 1; //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关}/*********************************************************************************************** *****关闭IAP 功能************************************************************************************************ *****/void IAP_Disable(){//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关IAP_CONTR = 0; //关闭IAP 功能IAP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用IAP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用IAP_ADDRH = 0;IAP_ADDRL = 0;}//MAX186 程序#ifndef _MAX186_H_#define _MAX186_H_#include <stc12c5a.h>sbit MAX186_SCLK_1 = P1^0;sbit MAX186_CS_1 = P1^1;sbit MAX186_DIN_1 = P1^2;sbit MAX186_DOUT_1 = P1^3;sbit MAX186_SCLK_2 = P1^4;sbit MAX186_CS_2 = P1^5;sbit MAX186_DIN_2 = P1^6;sbit MAX186_DOUT_2 = P1^7;unsigned int Max186_AD(unsigned char chan);#endif#include <max186.h>unsigned int Max186_AD(unsigned char chan){unsigned char i,kki,ch;unsigned int i_data,i_datatransfer,addata;switch(chan){case 0: ch=0x8E;break;case 1: ch=0xCE;break;case 2: ch=0x9E;break;case 3: ch=0xDE;break;case 4: ch=0xAE;break;case 5: ch=0xEE;break;case 6: ch=0xBE;break;case 7: ch=0xFE;break;default: ch=0xAE;break;}MAX186_CS_2=1;MAX186_SCLK_2=0;MAX186_CS_2=0;MAX186_SCLK_2=0;for(i=0;i<8;i++){unsigned char adaddresstransfer;adaddresstransfer=ch;adaddresstransfer=(adaddresstransfer>>(7-i))&0x01;MAX186_DIN_2=adaddresstransfer;MAX186_SCLK_2=1;for(kki=0;kki<2;kki++);MAX186_SCLK_2=0;}MAX186_CS_2=1;for(i=0;i<6;i++);MAX186_CS_2=0;MAX186_SCLK_2=1;for(i=0;i<12;i++){MAX186_SCLK_2=1;MAX186_SCLK_2=0;i_datatransfer=MAX186_DOUT_2;i_datatransfer=i_datatransfer<<(11-i);i_data=i_data|i_datatransfer;}addata=i_data;for(i=0;i<4;i++){MAX186_SCLK_2=1;MAX186_SCLK_2=0;}MAX186_CS_2=1;i_data=i_datatransfer=0;delay(5);return(addata);}//SMC12864-05.H #ifndef _SMC12864_05_H_#define _SMC12864_05_H_#include<types.h>void Init_LCD();void SetOnOFF(bit Switch);void Clean_LCD();void Check_LCD_Status();void Write_Cmd(INT8U Cmd);void Set_Adrr(INT8U x,INT8U y);void Write_Data(INT8U Data);void Disp_HZ(INT8U addr,const INT8U * pt,INT8U num); #endif#include<SMC12864_05.H>#include<STC12C5A.H>#include<intrins.h>#include<delay.h>sbit RS_CS = P2^7;sbit RW_SDI = P2^6;sbit E_CLK = P2^5;sbit Busy_Bit = P0^7;void Init_LCD(){Write_Cmd(0x30); //基本指令集delay(1);Write_Cmd(0x02); // 地址归位delay(1);Write_Cmd(0x0c); //整体显示打开,游标关闭delay(1);Write_Cmd(0x01); //清除显示delay(1);Write_Cmd(0x06); //游标右移delay(1);Write_Cmd(0x80); //设定显示的起始地址Clean_LCD();SetOnOFF(1);}void Clean_LCD(){RS_CS=0;RW_SDI=0;P0=0x01;E_CLK=1;delay(1);E_CLK=0;}void SetOnOFF(bit Switch){RS_CS=0;RW_SDI=0;if(Switch==1)P0=0x0F;else P0=0x08;E_CLK=1;delay(1);E_CLK=0;}void Write_Cmd(INT8U Cmd){Check_LCD_Status();RS_CS=0;RW_SDI=0;P0=Cmd;E_CLK=1;delay(1);E_CLK=0;}void Write_Data(INT8U Data){Check_LCD_Status();RS_CS=1;RW_SDI=0;P0=Data;E_CLK=1;delay(1);E_CLK=0;}void Check_LCD_Status(){RS_CS=0;RW_SDI=1;P0=0xFF;E_CLK=1;delay(1);E_CLK=0;while(!Busy_Bit);}/*******************************************函数名称:Disp_HZ功能:控制液晶显示汉字参数:addr--显示位置的首地址pt--指向显示数据的指针num--显示字符个数返回值:无********************************************/ void Disp_HZ(INT8U addr,const INT8U * pt,INT8U num) {INT8U i;Write_Cmd(addr);for(i = 0;i < (num*2);i++)Write_Data(*(pt++));}。