STC12C5A60S2 1602驱动程序

合集下载

STC12C5A60S2单片机PWM程序

STC12C5A60S2单片机PWM程序

STC12C5A60S2PWM程序
由于STC12C5A60S2单片机内部自带两路PWM,所以可以利用自带的PWM进行负载电压调节。

电路图如上,该程序的功能是利用按键S1对LED的亮度进行调节。

程序如下:
#include"STC12C5A.h"//注意这个头文件,用reg52是不行的,如果你没有的话,可以去百// //度文档里搜索“STC12C5A系列单片机头文件”,有我共享的头文件。

void delay(unsigned int cnt)
{
unsigned char i;
for(;cnt>0;cnt--)
for(i=0;i<250;i++);
}
void main()
{
CCON=0; //禁止寄存器CCON中CF位的中断)
CL=0; //PCA的16位计数器低八位
CH=0; //PCA的16位计数器高八位
CMOD=0x00; //选择系统时钟/12 为计数脉冲,则PWM的频率f=sysclk/256/12;
CCAP0H=0x80; // 占空比控制
CCAP0L=0x80;
PCA_PWM0=0x00; //控制占空比的第九位为0
CCAPM0=0x42; //允许P13作为PWM输出
CR=1; //启动PCA计数器
while(1)
{
if(P10==0)
{
delay(200);
while(P10==0);
CCAP0H+=10; //占空比调节
CCAP0L+=10;
}
}
}
欢迎阅读。

STC12C5A60S2定时器,STC12C5A60S2定时器程序

STC12C5A60S2定时器,STC12C5A60S2定时器程序

STC12C5A60S2 定时器,STC12C5A60S2 定时器程序
STC12C5A60S2 单片机集成了共4 个16 位定时器,两个与传统8051 兼容的定时器/计数器,16 位定时器T0 和T1,没有定时器2,但有独立波特率发生器做串行通讯的波特率发生器,再加上2 路PCA 模块可再实现2 个16 位定时器;
1. 基本特性
STC12C5A60S2 单片机集成了两个16 位定时/计数器。

1)寄存器
1.1)TMOD 定时器工作方式控制寄存器,包括13 位寄存器、16 位寄存器、8 位寄存器等;
1.2)TCON 定时器控制寄存器,主要包括定时器启动控制位等;
1.3)AUXR 辅助寄存器,用以设置分频;默认12 分频
1.4)TH0/1:定时器高8 位寄存器
1.5)TL0/1:定时器低8 位寄存器
定时器计算
STC12C5A60S2 系列是1T 的8051 单片机,为了兼容传统的8051,定时器0 和定时器1 复位后是传统8051 的速度,既12 分频,这是为了兼容传统8051。

但也可以不进行12 分频,实现真正的1T。

编译、下载目标代码,LED 灯以1s 间隔闪烁,说明我们的代码是正确的。

现在我们修改一下代码,关闭定时器T0 的12 分频,粉色字段为新增加代码。

stc12c5a60s2硬件spi驱动NRF24l01程序

stc12c5a60s2硬件spi驱动NRF24l01程序

stc12c5a60s2硬件spi驱动NRF24l01程序#include#include#define MODE 0 //MODE=1时为发送代码 MODE=0时为接收代码typedef unsigned char uchar;#define uint unsigned int//****************************************IO端口定义***************************************sfr SPCTL = 0xCE; //SPI Control Register SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 0000,0100sfr SPSTAT = 0xCD; //SPI Status Register SPIF WCOL - - - - - - 00xx,xxxxsfr SPDAT = 0xCF;sbit CE =P1^0;sbit CSN =P1^1;sbit IRQ =P1^2;sbit led = P2^0;//************************************************************* *****************************uchar bdata sta; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;//*********************************************NRF24L01***** ********************************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 32 uints TX payload#define RX_PLOAD_WIDTH 32 // 32 uints TX payloaduchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址uchar code Tx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb, 0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0x aa,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据uchar Rx_Buf[RX_PLOAD_WIDTH];//接收数据//***************************************NRF24L01寄存器指令******************************************************* #define READ_REG 0x00 // 读寄存器指令#define WRITE_REG 0x20 // 写寄存器指令#define RD_RX_PLOAD 0x61 // 读取接收数据指令#define WR_TX_PLOAD 0xA0 // 写待发数据指令#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令#define NOP 0xFF // 保留//*************************************SPI(nRF24L01)寄存器地址****************************************************#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式#define EN_AA 0x01 // 自动应答功能设置#define EN_RXADDR 0x02 // 可用信道设置#define SETUP_AW 0x03 // 收发地址宽度设置#define SETUP_RETR 0x04 // 自动重发功能设置#define RF_CH 0x05 // 工作频率设置#define RF_SETUP 0x06 // 发射速率、功耗功能设置#define STATUS 0x07 // 状态寄存器#define OBSERVE_TX 0x08 // 发送监测功能#define CD 0x09 // 地址检测#define RX_ADDR_P0 0x0A // 频道0接收数据地址#define RX_ADDR_P1 0x0B // 频道1接收数据地址#define RX_ADDR_P2 0x0C // 频道2接收数据地址#define RX_ADDR_P3 0x0D // 频道3接收数据地址#define RX_ADDR_P4 0x0E // 频道4接收数据地址#define RX_ADDR_P5 0x0F // 频道5接收数据地址#define TX_ADDR 0x10 // 发送地址寄存器#define RX_PW_P0 0x11 // 接收频道0接收数据长度#define RX_PW_P1 0x12 // 接收频道1接收数据长度#define RX_PW_P2 0x13 // 接收频道2接收数据长度#define RX_PW_P3 0x14 // 接收频道3接收数据长度#define RX_PW_P4 0x15 // 接收频道4接收数据长度#define RX_PW_P5 0x16 // 接收频道5接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置/******************************************延时函数********************************************************///长延时void Delay(unsigned int s){unsigned int i,j;for(i=0;i<1000;i++)for(j=0;j<s;j++);}//短延时void delay_ms(unsigned int x){unsigned int i,j;i=0;for(i=0;i<x;i++){j=108;while(j--);}}/************初始化5A spi***************/void Init_SPI(uchar speed){SPDAT=0; //初始化数据寄存器SPSTAT=0XC0; //清除状态寄存器SPCTL=0XD0|speed;//设置为主机模式主频不能超过2M//忽略SS 使能spi MSB SCLK空闲为0 第一个时钟边沿开始采集spi通信的频率为CUP_CLK/16}//SPDAT 读写一个字节//TxData:要写入的字节//返回值:读取到的字节uchar SPI_ReadWriteByte(uchar TxData){SPDAT=TxData; //发送一个bytewhile((SPSTAT&0x80)==0);SPSTAT=0XC0; //清除状态寄存器return SPDAT; //返回收到的数据}//读取SPI寄存器值//reg:要读的寄存器uchar SPI_Read_Reg(uchar reg){uchar reg_val;CSN = 0; //使能SPI传输SPI_ReadWriteByte(reg); //发送寄存器号reg_val=SPI_ReadWriteByte(0xFF);//读取寄存器内容CSN = 1; //禁止SPI传输return(reg_val); //返回状态值}// 向寄存器REG写一个字节,同时返回状态字节 reg寄存器地址value写入的数据uchar SPI_RW_Reg (uchar reg,uchar value){uchar status;CSN=0;status=SPI_ReadWriteByte(reg);//发送寄存器号SPI_ReadWriteByte(value); //写入寄存器的值CSN=1;return(status);}//写一个数据包uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status=SPI_ReadWriteByte(reg);for(byte_ctr=0; byte_ctrSPI_ReadWriteByte(*pBuf++);CSN = 1;return(status);}//读一个数据包uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) {uchar status,uchar_ctr;CSN = 0;status = SPI_ReadWriteByte(reg);for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_</uchars;uchar_ctr++)</x;i++)</s;j++);ctr]=SPI_ReadWriteByte(0xFF);CSN = 1;return(status);}#if MODE/*******************************发*****送*****模*****式*****代*****码*************************************/void TX_Mode(void){CE=0;SPI_RW_Reg(FLUSH_TX,0x00);SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写发送的地址 Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 写接受的地址 RX_Addr0 same as TX_Adr for Auto.AckSPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //使能自动应答Enable Auto.Ack:Pipe0SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //使能通道0 Enable Pipe0SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 自动重发功能设置 500us + 86us, 10 retrans...1aSPI_RW_Reg(WRITE_REG + RF_CH, 40); //收发频率SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 发射速率、功耗功能设置 TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR SPI_RW_Reg(WRITE_REG + RX_PW_P0, (unsigned char)RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);CE=1;delay_ms(100);}void Transmit(unsigned char * tx_buf){CE=0; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //装载接收端地址SPI_RW_Reg(FLUSH_TX,0x00); //清除FIFOSPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送delay_ms(150);}#else/*******************************接*****收*****模*****式*****代*****码*************************************//************************************************************** ****************************************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/************************************************************** ****************************************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) {// unsigned char revale=0;sta=SPI_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志if(RX_DR) // 判断是否接收到数据{SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferSPI_RW_Reg(FLUSH_RX,0xFF);//清除接受FIFOreturn 1; //读取数据完成标志}return 0;}/************************************************************** **************************************//*函数:void RX_Mode(void)/*功能:数据接收配置/************************************************************** **************************************/void RX_Mode(void){CE=0;// SPI_RW_Reg(FLUSH_RX,0x00);//清除接受FIFO//SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uchar*)RX_ADDRESS, RX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.AckSPI_RW_Reg(WRITE_REG + EN_AA, 0x01);//使能自动应答Enable Auto.Ack:Pipe0SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //连接通道0和地址 Enable Pipe0//SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1aSPI_RW_Reg(WRITE_REG + RF_CH, 125);//通信频率0~125 设置通信的频率 Select RF channel 40SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节SPI_RW_Reg(WRITE_REG + RF_SETUP,0X0F); //0x07 TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR// 设置TX发射参数,0db增益,2Mbps,低噪声增益开启SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F);//配置基本工作模式的参数CE=1;delay_ms(130);}//************************************串口初始化********************************************************* void StartUART( void ){ //波特率9600SCON = 0x50; //串口模式1 8bit 使能接收TMOD = 0x20;//定时器1模式2 8位自动重装// PCON=0x80; //19200TH1 = 0xFD;TL1 = 0xFD;// IE=0x90; //开总中断开串口中断EA=1;ES=1;TR1=1;//启动定时器1// TI=1;}//************************************通过串口将接收到数据发送给PC端**************************************void R_S_Byte(uint R_Byte){SBUF=R_Byte;while(TI==0);TI=0;}#endif/************************************主函数************************************************************/ uchar NRF24L01_Check(void){uchar buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};uchar i;SPI_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.SPI_Read_Buf(TX_ADDR,buf,5); //读出写入的地址for(i=0;i<5;i++) if(buf[i]!=0XA5) break;if(i!=5) return 1;//检测24L01错误return 0; //检测到24L01}void main()uint i=0;CE=0;CSN=1;led=0;Init_SPI(1);while(NRF24L01_Check())//检测不到24L01{delay_ms(500);delay_ms(500);led=!led;//DS0闪烁}#if MODE //发送模式代码TX_Mode();while(1){Transmit(Tx_Buf); //清除FIFODelay(10);sta=SPI_Read(READ_REG + STATUS);if(TX_DS){P1=sta; //8位LED显示当前STATUS状态发送中断应使bit5 = 1 灯灭Delay(100);SPI_RW_Reg(WRITE_REG + STATUS,sta);}if(MAX_RT) //如果是发送超时P1=0x0f; //发送超时时 8位LED灯 bit4 = 1 灯灭Delay(150);SPI_RW_Reg(WRITE_REG + STATUS,sta);}}#else //接收模式代码StartUART(); //串口初始RX_Mode(); //接受模式Delay(0);//防止编译警告while(1){if(nRF24L01_RxPacket(Rx_Buf)){for(i=0;i<tx_pload_width;i++){R_S_Byte(Rx_Buf[i]);led=0;}}led=1;}#endif}</tx_pload_width;i++)。

STC12C5A60S2定时器,STC12C5A60S2定时器程序

STC12C5A60S2定时器,STC12C5A60S2定时器程序
确的。现在我们修改一下代码,关闭定时器T0的12分频,粉色字段为新增
加代码。
STC12C5A60S2单片机集成了两个16位定时/计数器。
1)寄存器
1.1)TMOD定时器工作方式控制寄存器,包括13位寄存器、16位
寄存器、8位寄存器等;
1.2)TCON定时器控制寄存器,主要包括定时器启动控制位等;
1.3)AUXR辅助寄存器,用以设置分频;默认12分频
1.4)TH0/1:定时器高8位寄存器
1.5)TL0/1:定时器低8位寄存器
定时器计算
STC12C5A60S2系列是1T的8051单片机,为了兼容传统的8051,
定时器0和定时器1复位后是传统8051的速度,既12分频,这是为了兼容
传统8051。但也可以不进行12分频,实现真正的1T。
编译、下载目标代码,LED灯以1s间隔闪烁,说明我们的代码是正
STC12C5A60S2定时器,STC12C集成了共4个16位定时器,两个与传统8051
兼容的定时器/计数器,16位定时器T0和T1,没有定时器2,但有独立波特
率发生器做串行通讯的波特率发生器,再加上2路PCA模块可再实现2个
16位定时器;
1.基本特性

STC12C5A60S2单片机PWM程序

STC12C5A60S2单片机PWM程序

STC12C5A60S2单片机PWM程序两个头文件main.c#include <REG51.H>#include <intrins.h>#define U8 unsigned char#define U16 unsigned intvoid DelayMs(U8 ms);void PWM_clock(U8 clock); void PWM_start(U8 module,U8 mode);////////////////////// 延时子程序/////////////////////////////void DelayMs(U8 ms) // 在11.0592M 晶振下,stclOf 系列(单周期指令)的ms 级延时{U16 i;while(ms--){for(i = 0; i < 850; i++); }}//////////////////// 主函数入口////////////////////////////sfr CCON = 0xD8; //PCA 控制寄存器sfr CMOD = 0xD9; //PCA 模式寄存器sfr CCAPM0 = 0xDA; //PCA 模块0模式寄存器// 模块0对应P1.3/CEX0/PCA0/PWM0(STC12C5A60系列)sfr CCAPM1 = 0xDB; //PCA 模块1 模式寄存器// 模块1 对应P1.4/CEX1/PCA1/PWM1(STC12C5A60系列)sfr CL = 0xE9; //PCA 定时寄存器低位sfr CH = 0xF9; //PCA 定时寄存器高位sfr CCAP0L = 0xEA; //PCA 模块0的捕获寄存器低位sfr CCAP0H = 0xFA;//PCA模块0的捕获寄存器高位sfr CCAP1L = OxEB; //PCA 模块1的捕获寄存器低位sfr CCAP1H = 0xFB; //PCA 模块1的捕获寄存器高位sfr PCA_PWM0 = 0xF2; //PCA PWM 模式辅助寄存器0sfr PCA_PWM1 = 0xF3; //PCA PWM 模式辅助寄存器1sbit CF = 0xDF; //PCA 计数溢出标志位sbit CR = 0xDE; //PCA 计数器运行控制位sbit CCF1 = 0xD9; //PCA 模块1 中断标志sbit CCF0 = 0xD8; //PCA 模块0 中断标志//* CCAPOH = CCAPOL = 0XC0; // 模块0 输出占空因数为25%//* CCAPOH = CCAPOL = 0X80; // 模块0 输出占空因数为50%//* CCAPOH = CCAPOL = 0X40; // 模块0 输出占空因数为75%void PWM_clock(U8 clock);void PWM_start(U8 module,U8 mode);void PWM_clock(U8 clock){CMOD |= (clock<<1);CL = 0x00;CH = 0x00;void PWM_start(U8 module,U8 mode,U8 zkb) {CCAP0L = 0XC0;CCAP0H = 0XC0; // 模块 0 初始输出 占空因数为 25% CCAP1L = 0XC0; CCAP1H = 0XC0; // 模块 1 初始输出 占空因数为 25% if(module==0) {中断default: break;}}elseif(module==1){switch(mode){ switch(mode){case 0: CCAPM0 = 0X42;break; //case 1: CCAPM0 = 0X53;break; //中断case 2: CCAPM0 = 0X63;break; //中断case 3: CCAPM0 = 0X73;break; //模块0设置为8位PWM 输出,无中断 模块0设置为8位PWM 输出,下降沿产生 模块0设置为8位PWM 输出,上升沿产生case 0: CCAPM0 = CCAPM1 = 0X42;break; //出,无中断case 1: CCAPM0 = CCAPM1 = 0X53;break; //出,下降沿产生中断case 2: CCAPM0 = CCAPM1 = 0X63;break; //出,上升沿产生中断case 3: CCAPM0 = CCAPM1 = 0X73;break; //出,跳变沿产生中断default: break; case 0: CCAPM1 = 0X42;break; //case 1: CCAPM1 = 0X53;break; //中断case 2: CCAPM1 = 0X63;break; // 中断 case 3: CCAPM1 = 0X73;break; //中断default: break;}}elseif(module==2){switch(mode){模块1设置为8位PWM 输出,无中断 模块1设置为8位PWM 输出,下降沿产生 模块1设置为8位PWM 输出,上升沿产生模块0和1设置为8位PWM 输模块0和1设置为8位PWM 输 模块0和1设置为8位PWM 输 模块0和1设置为8位PWM 输}CR=1; //PCA 计数器开始计数}void PCA_Intrrpt(void) interrupt 7 {if(CCF0) CCF0=0;if(CCF1) CCF1=0; // 软件清零if(CF) CF=0; // 软件清零}void main(){TMOD|=0x02; /* timer 0 mode 2: 8-Bit reload */TH0=0xff;TR0=1;PWM_clock(2); // PCA/PWM 时钟源为定时器0 的溢出PWM_start(O,O); // 模块0,设置为PWM输出,无中断,初始占空因素为25% DelayMs(250);ITO=1; // 下降沿触发EXO=1; // 开中断OEA=1; // 开总中断while(1); // 等待中断产生,按下S15按键产生中断信号}#include "reg51.h"#define uchar unsigned char #define uint unsigned intsbit di=P3A7;uchar jishu=0x00; // 用来记录中断的次数void delay(uchar z){uchar i;for(i=0;i<z;i++);}/ """"""""""""""""""""""""""""""""""""// if n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n // 外部中断0 子函数void PWM_Select(void) interrupt 0 {U8 modjishu++; // 中断一次加1mod=jishu%3;switch(mod){case 0: CCAPM0 = 0X42;break; //0 设置为25%PW输出case 1: CCAPM0 = 0X53;break; //0 设置为50%PW输出case 2: CCAPM0 = 0X63;break; //0 设置为75%PW输出default: break;} delay(255);。

stc12c5a60s2 AD 程序

stc12c5a60s2  AD 程序
//AD速度设置。
#define ADC_SPEEDLL 0x00 //540 clocks
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define uchar unsigned char
#define uint unsigned int
/*LCD 各种端口的设置 */
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit LCD_PSB=P2^3;
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC开始标志位。
/*可写入 4*8 汉字,x的范围是1到4,y的范围是1到8*/
void lcd_string(uchar x,uchar y,char*str)
{
static uchar flag = 0;
uchar i = 0;
if(!flag)
{
lcd_init();
flag = 1;
case 3 : temp = 0x88;
break;
case 4 : temp = 0x98;
break;
default : temp = 0x80;
break;
}
pos = temp + col-1;
LCD_0(0,pos);
}
}
/*字符位置的选定*/

亲自调过的基于STC12C5A60S2的LCD1602显示屏程序

亲自调过的基于STC12C5A60S2的LCD1602显示屏程序
stc12c5a60s2单片机stc12c5a60s2资料stc12c5a60s2程序stc12c5a60s2封装stc12c5a60s2晶振stc12c5a60s2原理图stc12c5a60s2引脚图stc12c5a60s2手册stc12c5a60s2引脚stc12c5a60s2例程
#include"STC12C5A60S2.h"
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
P0=dictate; //将数据送人p0口,写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //当E由高电平变成低电平时,液晶模块开始
}
/********
函数功能:指定字符显示的地址
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //写指令时E为高脉冲,让E从0到1发生正跳变,所以应先置零
_nop_();
_nop_();

STC12C5A60S2的1602液晶屏显示【

STC12C5A60S2的1602液晶屏显示【

#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit lcdrs=P2^7;sbit lcden=P2^6;uchar code stringtable[4]={'a','b','c','d'};void delay(uint z) //1ms延时子程序{uint x,y;for(x=z;x>0;x--){for(y=240;y>0;y--);}}void write_com(com) //1602lcd写命令子程序{lcdrs=0;delay(2);//为开启写入命令的时间>后面程序执行时间和延长时间之和才行。

P0=com;lcden=1;delay(2);lcden=0;}void write_data(date) //1602lcd写数据子程序{lcdrs=1;delay(2);P0=date;lcden=1;delay(2);lcden=0;}void lcd_init(){delay(15);//读取子程序所用大约时间write_com(0x38);write_com(0x0e);write_com(0x06);}void main() //先让内容显示出来,在让它整体移动。

{uchar number,k;lcd_init();//主程序中须先声明屏幕的显示设置就像未知数须先定义一样。

while(1){write_com(0x80+0x09);//要先写明显示的初始地址,才能写入数据。

上行显示for(number=0;number<4;number++){write_data(stringtable[number]);}delay(3000);write_com(0x01); //清屏delay(10);write_com(0x80+0x40+0x09);//要先写明显示的初始地址,才能写入数据。

STC12C5A60(32)S2单片机AD采样-LCD1602液晶显示程序

STC12C5A60(32)S2单片机AD采样-LCD1602液晶显示程序
void lcd_int();//1602初始化
void lcd_locate(uchar x,uchar y);//显示定位(行,列)
void lcd_4_char(uint data_4char);//显示4位整型函数
/********写命令子函数********/
void lcd_write_com(uchar lcd_com)
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//延时4个时钟周期左右
while(!((ADC_CONTR & ADC_FLAG) == 0x10))//等待转换结束
adc_data = (ADC_RES & 0x03)* 256 + ADC_RESL; //转换结果计算
{
lcd_data_port = lcd_com;//指令送到数据接口
lcd_rs = 0;//选择命令
lcd_rw = 0;//选择写
lcd_en = 0;
delay_ms(1);
lcd_en = 1;
delay_ms(1);
lcd_en = 0;
}
/********写数据子函数********/
#define ADC_SPEED 0x40//设置为180个周期,ADC一次
#define ADC_START 0x08//ADC启动控制位设为开
#define ADC_FLAG 0X10//ADC结束标志位
//***第n通道ADC初始化函数***//
void ADC_int(uchar n)
{
n &= 0x07;//确保是第0~7通道
void lcd_write_data(uchar lcd_data)

Stc12c5a60s2 eeprom读写程序

Stc12c5a60s2   eeprom读写程序

IapId
{
uchar temp=0;
Lnum=IapReadByte(0x0000);
P0=Lnum;
//连接 led
KEY_ADD=1; //按键输入端口电平置高
KEY_DEC=1;
if(IapReadByte(0x0000)==0xff||h==0)
{
IapEraseSector(0x0000); IapProgramByte(0x0000,0x0a); Lnum=10;
// 去 stc 官网下载 or stc 最新下载程序有 stc 系列头文件
sbit h=P3^0; sbit KEY_ADD=P3^4; sbit KEY_DEC=P3^5; uchar Lnum;
//定义按键输入端口
void delay(uchar i) {
uchar j; while(i--) { for(j=0;j<125;j++); } } void IapIdle() { IAP_CONTR=0; IAP_CMD=0; IAP_TRIG=0; IAP_ADDRH=0X80; IAP_ADDRL=0; } uchar IapReadByte(uint addr) {
nop();
IapIdle();
}
void IapEraseSector(uint addr)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
nop();
//按一下 P3^0,会把修改后的数据存入 eeprom 的 0x0000 地址内。关闭单片机,再次打开,

STC12C5A60S2两路AD采集用LCD1602显示

STC12C5A60S2两路AD采集用LCD1602显示

STC12C5A60S2两路AD采集用LCD1602显示#include#include#include "stdio.h"#define ulong unsigned long#define uint unsigned int#define uchar unsigned charuchar data adc _at_ 0x30;uchar data adc1 _at_ 0x31;sbit E=P2^7; //1602使能引脚sbit RW=P2^6; //1602读写引脚sbit RS=P2^5; //1602数据/命令选择引脚void SendByte(unsigned char dat);void SendStr(unsigned char *s);void L1602_string(uchar hang,uchar lie,uchar *p);void L1602_char(uchar hang,uchar lie,char sign);uchar AD();uchar AD1();void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}void delay(){_nop_();_nop_();}void Delay(uint del){uint i,j;for(i=0;i<del;i++)< p="">for(j=0;j<=148;j++){}}/************************************************************** ******* 名称: bit Busy(void)* 功能: 这个是一个读状态函数,读出函数是否处在忙状态* 输入: 输入的命令值* 输出: 无*************************************************************** ********/ void Busy(void){bit busy_flag = 1;P0 = 0xff;RS = 0;delay();RW = 1;delay();E = 1;//Delay(1);while(1){busy_flag = (bit)(P0 & 0x80);if(busy_flag == 0){break;}}E = 0;}/************************************************************** ******* 名称: wcmd(uchar del)* 功能: 1602命令函数* 输入: 输入的命令值* 输出: 无*************************************************************** ********/ void wcmd(uchar del){RS = 0;delay();RW = 0;delay();E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/************************************************************** ******* 名称: wdata(uchar del)* 功能: 1602写数据函数* 输入: 需要写入1602的数据* 输出: 无*************************************************************** ********/void wdata(uchar del){delay();RS = 1;delay();RW = 0;delay();E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/************************************************************** ******* 名称: L1602_init()* 功能: 1602初始化,请参考1602的资料* 输入: 无* 输出: 无*************************************************************** ********/ void L1602_init(void){Delay(15);wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);wcmd(0x38);Busy();wcmd(0x08);Busy();wcmd(0x01);Busy();wcmd(0x06);Busy();wcmd(0x0c);}/************************************************************** ******* 名称: L1602_char(uchar hang,uchar lie,char sign)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下L1602_char(1,5,'b')* 输入: 行,列,需要输入1602的数据* 输出: 无*************************************************************** ********/void L1602_char(uchar hang,uchar lie,char sign){uchar a;if(hang == 1){a = 0x80;}if(hang == 2){a = 0xc0;}a = a + lie - 1;Busy();wcmd(a);Busy();wdata(sign);}/************************************************************** ******* 名称: L1602_string(uchar hang,uchar lie,uchar *p)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下L1602_string(1,5,"ab cd ef;")* 输入: 行,列,需要输入1602的数据* 输出: 无*************************************************************** ********/ void L1602_string(uchar hang,uchar lie,uchar *p) {uchar a;if(hang == 1){a = 0x80;}if(hang == 2){a = 0xc0;}a = a + lie - 1;while(1){Busy();wcmd(a);Busy();wdata(*p);a++;p++;if((*p == '\0')||(a==0x90)||(a==0xd0)){break;}}}uchar AD(){ulong i;uchar star;ADC_CONTR|=0x80;for(i=0;i<10000;i++);P1ASF=0x01;ADC_CONTR|=0XE1;for(i=0;i<10000;i++); while(1){ADC_CONTR|=0x08; star=0;while(star==0){star=ADC_CONTR&0x10; }ADC_CONTR&=0x00; adc=ADC_RES;//adc<<=2;//adc+=ADC_RESL; return adc;}}uchar AD1(){ulong i;uchar star;ADC_CONTR|=0x80;for(i=0;i<10000;i++);P1ASF=0;ADC_CONTR|=0XE0;for(i=0;i<10000;i++);while(1){ADC_CONTR|=0x08;star=0;while(star==0){star=ADC_CONTR&0x10; }ADC_CONTR&=0x00;adc1=ADC_RES;// adc1<<=2;// adc1+=ADC_RESL; return adc1;}}void main(){float i,j;unsigned char a[16]; unsigned char b[16];L1602_init();while(1){{i=AD()*5/256;sprintf(a," DA1=%4.2f v",i); L1602_string(2,0,a); DelayMs(1);j=AD1()*5/256;sprintf(b," DC2=%4.2f v",j);L1602_string(1,0,b); }}}</del;i++)<>。

STC12C5A60S2单片机实现音频信号的频谱显示(在LCD上显示)

STC12C5A60S2单片机实现音频信号的频谱显示(在LCD上显示)

利用STC12C5A60S2单片机实现音频信号的频谱显示(在LCD上显示)思路:外来音频信号经过51单片机,在单片机中进行频谱分析,并将结果显示在LCD(12864或1602)上要求:频谱显示如同千千静听播放音乐时的频谱显示希望各位高手能给出详细的解决方案,感激。

51做FFT有些困难,可以使用增强型(RAM)的51机子进行参考程序:#include<STC12C5A.H>#define uchar unsigned char#define uint unsigned int#define channel 0x01 //设置AD通道为 P1.1//---------------------------------------------------------------------sbit SDA_R=P1^2;sbit SDA_R_TOP=P1^3;sbit SDA_G=P1^4;sbit SDA_G_TOP=P1^5;sbit STCP=P1^6;sbit SHCP=P1^7;//---------------------------------------------------------------------//----------------------------------------------------------------------------------------------------------------------//放大128倍后的sin整数表(128)code char SIN_TAB[128] = { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102,105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126, 126, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112,108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30,-36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121,-123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102,-98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6 };//放大128倍后的cos整数表(128)code char COS_TAB[128] = { 127, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94,89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59,-65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, -94, -89, -85, -80,-75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70,75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126 };//采样存储序列表code char LIST_TAB[128] = { 0, 64, 32, 96, 16, 80, 48, 112,8, 72, 40, 104, 24, 88, 56, 120,4, 68, 36, 100, 20, 84, 52, 116,12, 76, 44, 108, 28, 92, 60, 124,2, 66, 34, 98, 18, 82, 50, 114,10, 74, 42, 106, 26, 90, 58, 122,6, 70, 38, 102, 22, 86, 54, 118,14, 78, 46, 110, 30, 94, 62, 126,1, 65, 33, 97, 17, 81, 49, 113,9, 73, 41, 105, 25, 89, 57, 121,5, 69, 37, 101, 21, 85, 53, 117,13, 77, 45, 109, 29, 93, 61, 125,3, 67, 35, 99, 19, 83, 51, 115,11, 75, 43, 107, 27, 91, 59, 123,7, 71, 39, 103, 23, 87, 55, 119,15, 79, 47, 111, 31, 95, 63, 127};uchar COUNT=0,COUNT1=0,ADC_Count=0,LINE=15,G,T;uchar i,j,k,b,p;int Temp_Real,Temp_Imag,temp; // 中间临时变量uint TEMP1;int xdata Fft_Real[128];int xdata Fft_Image[128]; // fft的虚部uchar xdata LED_TAB2[64]; //记录漂浮物是否需要停顿一下uchar xdata LED_TAB[64]; //记录红色柱状uchar xdata LED_TAB1[64]; //记录漂浮点void Delay(uint a){while(a--);}void FFT(){ //uchar X;for( i=1; i<=7; i++) /* for(1) */{b=1;b <<=(i-1); //碟式运算,用于计算隔多少行计算例如第一极 1和2行计算,,第二级for( j=0; j<=b-1; j++) /* for (2) */{p=1;p <<= (7-i);p = p*j;for( k=j; k<128; k=k+2*b) /* for (3) 基二fft */{Temp_Real = Fft_Real[k]; Temp_Imag = Fft_Image[k]; temp = Fft_Real[k+b];Fft_Real[k] = Fft_Real[k] +((Fft_Real[k+b]*COS_TAB[p])>>7) + ((Fft_Image[k+b]*SIN_TAB[p])>>7); Fft_Image[k] = Fft_Image[k] -((Fft_Real[k+b]*SIN_TAB[p])>>7) + ((Fft_Image[k+b]*COS_TAB[p])>>7); Fft_Real[k+b] = Temp_Real -((Fft_Real[k+b]*COS_TAB[p])>>7) - ((Fft_Image[k+b]*SIN_TAB[p])>>7); Fft_Image[k+b] = Temp_Imag + ((temp*SIN_TAB[p])>>7) -((Fft_Image[k+b]*COS_TAB[p])>>7);// 移位.防止溢出. 结果已经是本值的 1/64 Fft_Real[k] >>= 1;Fft_Image[k] >>= 1;Fft_Real[k+b] >>= 1;Fft_Image[k+b] >>= 1;}}}// X=((((Fft_Real[1]*Fft_Real[1]))+((Fft_Image[1]*Fft_Image[1])))>>7);Fft_Real[0]=Fft_Image[0]=0; //去掉直流分量// Fft_Real[63]=Fft_Image[63]=0;for(j=0;j<64;j++){TEMP1=((((Fft_Real[j]*Fft_Real[j]))+((Fft_Image[j]*Fft_Image[j])))>>1);//求功率if(TEMP1>1)TEMP1--;else TEMP1=0;if(TEMP1>31)TEMP1=31;if(TEMP1>(LED_TAB[j]))LED_TAB[j]=TEMP1;if(TEMP1>(LED_TAB1[j])){ LED_TAB1[j]=TEMP1;LED_TAB2[j]=18; //提顿速度=12}}}void Init(){//-----------------------------------------------------------------------------------P1ASF = 0x02; //0000,0010, 将 P1.1 置成模拟口AUXR1 &=0xFB; //1111,1011, 令 ADRJ=0EADC=1; //AD中断打开ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel;//1110 1001 1打开 A/D (ADC_POWER)转换电源;11速度为70周期一次;//0中断标志清零;1启动adc(ADC_START);001AD通道打开(这里为P1.1);//-----------------------------------------------------------------------------------P2M0=1;P0M0=1;TMOD=0X12;TH0=0x30; //大约20K的采样率(要完整频段需40K以上。

STC12C5A60S2 双串口使用程序

STC12C5A60S2 双串口使用程序

STC12C5A60S2 双串口使用程序(已经验证成功)#include <stc12c5a60s2.h>#include "intrins.h"#define uchar unsigned char#define S2RI 0x01 // 串口2接收中断请求标志位#define S2TI 0x02 // 串口2发送中断请求标志位//================================================// 对于将P4.4、P4.5当做I/O口使用必须添加的定义||//================================================sfr p4sw=0xbb; // 需在主函数文件中做相应设置4、5、6为1(作为I/O口使用)/*sbit button1=P4^3;sbit button2=P4^4;sbit button3=P4^5;sbit button4=P4^6;*/uchar code temp1[]={" 白云:“我可是个名人”"};uchar code temp2[]={" 黑土:“啥名人啊,你就是个人名”"};uchar code temp3[]={" 小崔:“诶,大叔大妈,你俩都冷静冷静”"};uchar code temp4[]={" 观众:“哈哈哈哈”"};/*void delay_1ms(uchar ii) // 误差-0.018084490741us{unsigned char a,b;for(; ii>0; ii--)for( b = 18; b>0; b--)for( a = 152; a>0; a--);_nop_(); //if Keil,require use intrins.h}void delay1s(void) //误差-0.000000000125us{unsigned char a,b,c;for( c = 212; c>0; c--)for( b = 160; b>0; b--)for( a = 80; a>0; a--);_nop_(); //if Keil,require use intrins.h_nop_(); //if Keil,require use intrins.h}*///************************ 串口通信部分******************************uchar wj_uun = '!'; // 用于存放串口1接收的字符uchar wj_uun2 = '?'; // 用于存放串口2接收的字符void bt_uart_init() // 单片机双串口初始化{//SCON=0X50; // SM0=0 SM1=1 SM2=0 REN=1SM0 = 0; // 串口工作方式1:1位起始位,8位数据位,1位停止位允许串口接收SM1 = 1;REN = 1; // 允许串口接收//RI=1; // 接收标志位,0:正在接收1:接收完毕(如果RI=1就一直执行串口中断) TMOD = 0X20; // 定时器T1工作方式2TH1 = 0XFD; // 9600bit/s下的定时器初值TL1 = 0XFD;TR1 = 1; // 启动定时器T1EA = 1; // 开总中断ES = 1; // 开串行口中断S2CON = 0x50; // 串口2工作在方式1 10位异步收发S2SM0=0 S2SM1=1 S2REN=1允许接收BRT = 0XFD; // 9600bit/s下的独立波特率发生器初值AUXR = 0x10; // 辅助寄存器:0001 0000 ->BRTR=1:独立波特率发生器开始计数,S2SMOD=0:波特率不加倍,BRTx12=0:独立波特率每12个时钟计数一次IE2 = 0x01; // 开串口2中断0000 0001->ES2=1// AUXR1 = 0x10; // 0001 0000->S2_P4=1:UART2从P1口(RxD2:P1.2 TxD2:P1.3)切换到P4口(RxD2:P4.2 TxD2:P4.3) 否则默认都为P1口}/************** 串口1发送函数*****************/void s1_send_char(uchar dat) // 发送端(发送的是字符){SBUF = dat; // 将字符送入发送缓冲寄存器while(!TI); // TI为发送状态标志位,0:发送中1:发送结束TI = 0; // 手动清零标志位}void s1_send_string(uchar *pt) // 通过调用发送字符函数来发送字符数组{while(*pt != '\0'){s1_send_char(*pt++);}}/************** 串口2发送函数*****************/void s2_send_char(uchar dat2) // 发送端(发送的是字符){S2BUF = dat2; // 将字符送入串口2的发送缓冲寄存器while(!(S2CON&S2TI)); // 判断发送是否结束:S2CON.bit2 = 0:发送中1:发送结束S2CON &= ~S2TI; // 手动清零标志位,令S2CON.bit2 = 0}void s2_send_string(uchar *pt2) // 通过调用发送字符函数来发送字符数组{while(*pt2!='\0'){s2_send_char(*pt2++);}}/************** 串口1中断程序*****************/void bt_serial_1() interrupt 4 // 中断编号4为串行口1中断{if(RI) // 接收标志位,0:正在接收1:接收完毕(如果RI=1就一直执行中断){RI = 0; // 同样需要手动清零wj_uun = SBUF; // 将接收缓冲器接收的字符送入变量中}}/************** 串口2中断程序*****************/void bt_serial_2() interrupt 8 // 中断编号8为串行口2中断{if(S2CON&S2RI) // 接收标志位: S2CON.bit1 = 0:正在接收1:接收完毕(如果RI=1就一直执行中断){S2CON &= ~S2RI; // 同样需要手动清零,令S2CON.bit1 = 0wj_uun2 = S2BUF; // 将串口2接收到的字符送入变量中}}void main(void){bt_uart_init(); // 串口初始化p4sw = 0x70; // 0111 0000 对应的4、5、6脚设置成功通用I/O口while(1){/*if(wj_uun != '!') // 串口1接收{s1_send_char(wj_uun); // 串口1发送wj_uun = '!';}*/if(wj_uun2 != '?') // 串口2接收{s2_send_char(wj_uun2); // 串口2发送wj_uun2 = '?';}}}。

STC12C5A60S2自带10位AD测量电压值LCD1602显示(C程序)

STC12C5A60S2自带10位AD测量电压值LCD1602显示(C程序)

/*---------------------------------------------------------------------------------------------------------------------------*/ /*--************************功能【AD 转换,液晶显示】**************************--*//*--************************芯片:【STC12C5A60S2】******************************--*//*--************************液晶:【LCD1602】***********************************--*//*--************************ADC管脚:【P1.0~P1.7】***************************--*//*--************************检测范围:【0.00~4.99V】***************************--*//*---------------------------------------------------------------------------------------------------------------------------*/ #include"reg52.h"#include"intrins.h"typedef unsigned char uchar;typedef unsigned int uint;#define _Nop() _nop_()/*------------------------以下为LCD1602显示模块定义-----------------------*/unsigned char data_char_table[]={"0123456789ABCDEF"}; //LCD 数据unsigned char Lcd_Dis1_table[]= {"Position:No. "}; //第一行显示框架unsigned char pos_char_table[]= {" D "}; //显示位置unsigned char Lcd_Dis2_table[]= {"Voltage: V"}; //第二行显示框架unsigned char num_char_table[]= {" 9A.CD V"}; //显示位置sbit lcd_rs_port=P2^7; //定义LCD 控制端口,根据硬件调整sbit lcd_rw_port=P2^6;sbit lcd_en_port=P2^4;#define lcd_data_port P0void lcd_delay(uchar ms);//LCD1602延时void lcd_busy_wait(); //LCD1602忙等待void lcd_command_write(uint command); //LCD1602命令字写入void lcd_system_reset(); //LCD1602初始化voidlcd_char_write(uint x_pos,y_pos,lcd_dat); //LCD1602字符写入voidlcd_bad_check(); //LCD1602坏点检查void Num_to_Disp(uchar i, uint Num); //显示数据处理void LcdDisp(uchar j,uint num); //液晶显示函数/*------------------------以下为ADC 相应寄存器初始化及端口定义-------------*//***** 定义与ADC 相关的特殊功能寄存器*****/sfr ADC_CONTR = 0xBC; //ADC 控制寄存器sfr ADC_RES = 0xBD; //ADC hight8-bit result register sfr ADC_RESL = 0xBE; //ADC low2-bit result registersfr P1ASF = 0x9D; //P1 口功能控制寄存器P1ASF/************定义相应操作位***************/#define ADC_POWER0x80//ADC 电源控制位,0:关闭,1:打开#define ADC_FLAG 0x10//ADC 结束标志位#define ADC_START0x08 //ADC 启动控制位#define ADC_SPEEDLL 0x00 //540clocks___________选择转换速度/*------------------------以下为相关函数声明------------------------------*/void InitADC();uuuu GetADCResult(uchar ch);vvvv Delay(uint n);void delay_1ms(uchar x);/*-------------------------------- 主函数--------------------------------*/ void main(){//ADC 初始化//延时程序uchar i;lcd_system_reset(); //LCD1602 初始化lcd_bad_check(); //LCD1602 坏点检查InitADC(); //初始化ADC 特殊功能寄存器while(1){i = 0;while(i < 7){LcdDisp(i, GetADCResult(i)); //液晶1602 显示输入电压值(P1.0 -P1.7)Delay(1000);i++;}}}/*-------------------------------- ADC 取值------------------------------*/uint GetADCResult(uchar ch){ADC_CONTR= ADC_POWER | ADC_SPEEDLL | ch | ADC_START;_nop_(); //Must wait before inquiry_nop_();_nop_();_nop_();while(!(ADC_CONTR & ADC_FLAG)); //Wait complete flagADC_CONTR&=ADC_FLAG;//Close ADCreturn (ADC_RES*4+ ADC_RESL); //Return ADC result}/*---------------------------- 初始化ADC 特殊功能寄存器-------------------*/void InitADC(){P1ASF=P1|0x3f;//Set P1.0 - P1.5 as analog input portADC_RES = 0; //Clear previous resultADC_RESL =0;ADC_CONTR= ADC_POWER | ADC_SPEEDLL ;Delay(20); //ADC power-on delay and Start A/D conversion}/*---------------------------- LCD1602相应函数---------------------------*////////////////以下为LCD 显示数据处理/////////////////void Num_to_Disp(uchar i, uint Num){float NUM;int xx,yy,zz;NUM=(Num*5/1024.0); //计算公式:10-bit A/D Conversion Result = 1024x(Vin/Vcc) xx = (int)NUM;yy= (int)((NUM-(float)(xx)) * 10);zz= (int)((NUM-(float)(xx)) * 100)%10;num_char_table[9] = data_char_table[xx/ 10]; //电压值十位num_char_table[10]=data_char_table[xx% 10]; //电压值个位num_char_table[12]=data_char_table[yy]; //电压值小数点后一位num_char_table[13]=data_char_table[zz]; //电压值小数点后两位?pos_char_table[13]=data_char_table[i]; //当前ADC接口}//////////////////以下为LCD 显示////////////////////void LcdDisp(uchar j,uint num){uint i=0;for (i=0;i<16;i++){lcd_char_write(i,0,Lcd_Dis1_table[i]);lcd_char_write(i,1,Lcd_Dis2_table[i]); //显示框架}Num_to_Disp(j,num);lcd_char_write(13,0,pos_char_table[13]);for(i =9;i<14;i++){lcd_char_write(i,1,num_char_table[i]); //显示电压}delay_1ms(100);}//////////////以下是LCD1602驱动程序////////////////void lcd_delay(uchar ms)/*LCD1602 延时*/{uchar j;while(ms--){for(j=0;j<250;j++){;}}}void lcd_busy_wait()/*LCD1602忙等待*/{lcd_rs_port=0;lcd_rw_port=1;lcd_en_port=1;lcd_data_port=0xff;while(lcd_data_port&0x80);lcd_en_port=0;}void lcd_command_write(uint command) /*LCD1602命令字写入*/ {lcd_busy_wait();lcd_rs_port=0;lcd_rw_port=0;lcd_en_port=0;lcd_data_port= command;lcd_en_port=1;lcd_en_port=0;}void lcd_system_reset()/*LCD1602 初始化*/{lcd_delay(20);lcd_command_write(0x38);lcd_delay(100);lcd_command_write(0x38);lcd_delay(50);lcd_command_write(0x38);lcd_delay(10);lcd_command_write(0x08);lcd_command_write(0x01);lcd_command_write(0x06);lcd_command_write(0x0c);}void lcd_char_write(uint x_pos,y_pos,lcd_dat) /*LCD1602 字符写入*/ {x_pos &= 0x0f;/*X 位置范围0~15*/y_pos &= 0x01;/*Y 位置范围0~1*/if(y_pos==1)x_pos+=0x40;x_pos += 0x80;lcd_command_write(x_pos);lcd_busy_wait();lcd_rs_port=1;lcd_rw_port=0;lcd_en_port=0;lcd_data_port=lcd_dat;lcd_en_port=1;lcd_en_port=0;}void lcd_bad_check()/*LCD1602坏点检查*/{char i,j;for(i=0;i<2;i++){for(j=0;j<16;j++){lcd_char_write(j,i,0xff);}}lcd_delay(200);lcd_delay(200);lcd_delay(200);lcd_delay(100);lcd_delay(200);lcd_command_write(0x01);/* clear lcd disp */}//////////////////以上是LCD1602驱动程序/////////////////*-----------------------------void Delay(uint n){uint x;while(n--){}延时程序x = 500;while(x--);---------------------------*/}/*1MS 为单位的延时程序*/ void delay_1ms(uchar x){uchar j;while(x--){for(j=0;j<125;j++){;}}}。

STC12C5A60S2单片机实现AD采样并液晶显示

STC12C5A60S2单片机实现AD采样并液晶显示

STC12C5A60S2单片机实现AD采样并液晶显示STC12C5A60S2是一款高性能、低功耗的8051内核单片机。

以下是一种基于该单片机进行AD采样并液晶显示的实现方案。

请注意,由于字数限制,以下内容是基本的框架和步骤,具体细节还需要根据具体需求进行调整。

1.准备材料和设备:-STC12C5A60S2单片机主控板-16x2液晶显示屏-AD转换器(例如MCP3008)-电压传感器模块-连接线、电阻、电容等2.连接硬件:-将液晶显示屏的VCC、GND和信号线(如RS、R/W、EN、D0-D7等)连接到STC12C5A60S2单片机对应的引脚。

-将AD转换器的VCC、GND和信号线(如CLK、DOUT、DIN、CS等)连接到STC12C5A60S2单片机对应的引脚。

-将电压传感器模块的输出引脚连接到AD转换器的输入引脚。

3.编写代码:-使用C语言编写STC12C5A60S2单片机的代码,包括初始化设置、AD 采样、数据处理和液晶显示等部分。

-在初始化设置中,设置AD转换器的引脚和时钟,配置液晶显示屏的引脚和参数。

-在AD采样部分,通过SPI通信协议与AD转换器进行通信,获取电压传感器模块的输出电压值。

-在数据处理部分,将采样到的原始数据经过相应的处理,如校正、换算等。

-在液晶显示部分,将处理后的数据显示到液晶屏上,并通过适当的界面设计和显示格式展示结果。

4.烧录程序:-使用相应的编程工具将编写好的代码烧录到STC12C5A60S2单片机。

-确保烧录成功,并断开编程工具的连接。

5.调试测试:-连接好硬件后,给电压传感器模块供电,确保电压输入正常。

-上电运行STC12C5A60S2单片机,液晶显示屏应显示出AD采样后的结果。

-对不同的输入电压进行测试,观察液晶屏上的显示结果是否与实际输入电压相符。

请注意,以上仅是基本的框架和步骤,实际应用中还需要根据具体需求和应用场景进行相应的优化和调整。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
函数名称: UART1_INIT
功 能: 初始化MCU串口(带1位奇校验)
参 数: 无
返回值 : 无
********************************************************************/
void UART1_INIT(void)
函数名称: IRQ_INIT
功 能: 中断初始化
参 数: 无
返回值 : 无
********************************************************************/
void IRQ_INIT(void)
{
// EX0 = 1; //开外部中断0
函数名称: Delay_nop
功 能: 延迟指定CPU cycle
参 数: dwTime - 延迟的CPU周期数
返回值 : 无
********************************************************************/
void Delay_nop (unsigned int dwTime)
ES = 1; //开UART1中断
IE2 |= 0x01; //开UART2中断
// IE2 |= 0x02; //开SPI中断
EADC = 1; //开ADC中断
EA = 1; //开总中断
}
/********************************************************************
#define NONE_PARITY 0 //无校验位
#define ODD_PARITY 1 //奇校验
#define EVEN_PARITY 2 //偶校验
#define MARK_PARITY 3 //标记校验
#define SPACE_PARITY 4 //空校验
{
if (RI)
{
RI = 0;
temp = SBUF;
cache_L1[L1_R] = temp;
L1_R++;
if (L1_R >= 100)
{
L1_R = 0;
}
}
if (TI)
{
TI = 0;
busy1 = 0;
{
while (busy1);
ACC = CH;
if (P)
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 0; //置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
函数名称: UART2_INIT
功 能: 初始化MCU串口(带1位奇校验)
参 数: 无
返回值 : 无
********************************************************************/
void UART2_INIT(void)
sbit lcden = P3^4;
sbit lcdrs = P3^5;
sbit ledla = P2^5;
sbit dula = P2^6;
sbit wela = P2^7;
/****************************cache**************************/
{
while (dwTime--);
}
/********************************************************************
函数名称: Delay_ms
功 能: 延迟指定的ms数
参 数: z - 延迟的ms数
返回值 : 无
函数名称: IRQ
功 能: 中断函数
参 数: 无
返回值 : 无
********************************************************************/
void IRQ_external0(void) interrupt 0
{
}
/********************************************************************
函数名称: Time_INIT
功 能: 定时器初始化
参 数: 无
返回值 : 无
********************************************************************/
#define PARITYBIT EVEN_PARITY
bit busy1, busy2;
#define S2RI 0x01
#define S2TI 0x02
#define S2RB8 0x04
#define S2TB8 0x08
/****************************1602**************************/
TB8 = 1; //置校验位为1
#endif
}
else
void Time_INIT(void)
{
// TMOD = 0x11;
// TH0 = (65535-105)/256;
// TL0 = (65535-105)%256;
// TH1 = 0x00;
// TL1 = 0x00;
}
/********************************************************************
********************************************************************/
void Delay_ms (unsigned int z)
{
unsigned int x, y;
for (x=0; x<z; x++)
for (y=0; y<580; y++);
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void UART1_SENDCH(unsigned char CH);
/********************************************************************
}
void IRQ_Time0(void) interrupt 1
{
}
void IRQ_external1(void) interrupt 2
{
}
void IRQ_Time1(void) interrupt 3
{
}
void IRQ_UART1(void) interrupt 4
函数名称: UART1_SENDCH
功 能: 从串口发送一个字节(1位奇校验)
参 数: CH ---- 发送的1字节数据
返回值 : 无
********************************************************************/
void UART1_SENDCH(unsigned char CH)
unsigned int temp;
unsigned char L1_R = 0;
unsigned char L1_T = 0;
unsigned char L2_R = 0;
unsigned char L2_T = 0;
unsigned char xdata cache_L1[100] = {0};
#define ADC_FLAG 0x10 //ADC complete flag
#define ADC_START 0x08 //ADC start control bit
#define ADC_SPEEDLL 0x00 //420 clocks
{
S2CON = 0xd0;
BRT = -(FOSC/32/BAUD); //设置独立波特率发生器的重载初值
AUXR = 0x14; //独立波特率发生器工作在1T模式
// IPH2 = 0x01;
// IP2 = 0x01;
}
/********************************************************************
// IT0 = 0; //为边沿触发方式(下降沿有效)
// EX1 = 1; //开外部中断1
// IT1 = 0; //为边沿触发方式(下降沿有效)
// ET0 = 1; //开定时器0中断
// ET1 = 1; //开定时器1中断
#define ADC_SPEEDL 0x20 //280 clocks
#define ADC_SPEEDH 0x40 //140 clocks
#define ADC_SPEEDHH 0x60 //70 clocks
#define ADC_CHS_7 0x07
{
L2_R = 0;
}
}
if (S2CON & S2TI)
相关文档
最新文档