单片机源程序如下:
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
#include "lcd016.h"
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
#define LCD_Data_Port P0
#define BAUD 9600
#define FOSC 12000000L //12mhz
sbit ADCS=P1^0;
sbit ADCLK=P1^1;
sbit ADDI=P1^2;
sbit ADDO=P1^2;
sbit LED=P1^4;
sbit ld=P3^7;
sbit SW=P1^7;
unsigned char cmd; // 存储蓝牙模块发送的命令
uint dat = 0x00; //AD值
uchar adc=0;//存储adc0832值
uint voltage = 0;
uchar pwm=0;//PWM占空比参数
uchar time=0;
uchar LED_buffer1[16] = {"ADC:000LX"};//ADC显示缓冲
uchar LED_buffer2[16] = {"voltage:0.00V"};//电压显示缓冲
sbit UART_TX=P3^1; // 定义蓝牙模块 TX 引脚
sbit UART_RX=P3^0; // 定义蓝牙模块 RX 引脚
/*------------------------------------------------
延时函数,含有输入参数 unsigned int t,无返回值
unsigned int 是定义无符号整形变量,其值的范围是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
void UART_Init() // 定义串口初始化函数
{
SCON=0x50; // SCON 寄存器配置,工作方式为模式 1,允许接收和发送
TMOD=0x20; // TMOD 寄存器配置,使用波特率发生器,不用自动重载
PCON=0x00; //波特率不加倍
TH1=(65536 - (FOSC / 12 / BAUD)); // 定时器 1 的重装值,用于产生 9600 波特率
TL1=(65536 - (FOSC / 12 / BAUD)); //(65536 - (FOSC / 12 / BAUD))
RI=0;
TI=0; //清0发送中断标志位
ES=1; // 打开串口中断开关
TR1=1; // 启动定时器 1
PS=1; //设置串口优先级第一
}
void UART_SendByte(unsigned char dat) // 定义串口发送函数
{
SBUF=dat; // 将要发送的数据存入 SBUF
while(!TI); // 等待数据发送完成
TI=0; // 清除发送标志位
}
unsigned char UART_ReceiveByte() // 定义串口接收函数
{
while(!RI); // 等待数据接收完成
RI=0; // 清除接收标志位
return SBUF; // 返回接收到的数据
}
// 从ADC读取数据的函数
uchar ADC_read_data(unsigned char channel)
{
unsigned char i = 0;
unsigned char j;
unsigned int dat = 0;
unsigned char ndat = 0;
if (channel == 0) channel = 2;//通道1
if (channel == 1) channel = 3;//通道2
ADDI = 1;//输入引脚拉高
_nop_();//延时1us
_nop_();//延时1us
ADCS = 0;//片选
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 1;//拉高时钟
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 0;//拉低时钟
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 1;//拉高时钟
ADDI = channel & 0x1;
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 0;//拉低时钟
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 1;//拉高时钟
ADDI = (channel >> 1) & 0x1;
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 0;//拉低时钟
ADDI = 1;//输出1
_nop_();//延时1us
_nop_();//延时1us
dat = 0; //存储清零
for (i = 0; i < 8; i++) //循环8次
{
dat |= ADDO;//读取引脚
ADCLK = 1; //拉高时钟
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 0;//拉低时钟
_nop_();//延时1us
_nop_();//延时1us
dat <<= 1;//左移 最低位从外面进去,最高位往左顶依旧是最高位 即0832数据最高位先进去
if (i == 7) dat |= ADDO;//读取引脚
}
for (i = 0; i < 8; i++)//循环8次
{
j = 0;
j = j | ADDO; //读取引脚
ADCLK = 1; //拉高时钟
_nop_();//延时1us
_nop_();//延时1us
ADCLK = 0; //拉低时钟
_nop_();//延时1us
_nop_();//延时1us
j = j << 7; //左移7位
ndat = ndat | j; //合并数据
if (i < 7) ndat >>= 1;//去掉符号
}
ADCS = 1; //清除片选
ADCLK = 0;//拉低时钟
ADDO = 1; //输出1
dat <<= 8;//数据移位
dat |= ndat;//合并数据
return(ndat);
}
void init_timer1()//定时器1的初始化函数
{
TMOD|=0X01; //设置计时器1为工作模式1,计时器0为工作模式1
TH0=0X3c; //设置计时器1的计数器高位为0x3C,让定时器1产生一个50ms的中断信号
TL0=0XB0; //设置计时器1的计数器低位为0xB0
ET0=1; //打开定时器1中断允许
EA=1; //打开总中断
TR0=1; //打开计时器1,若是定时器0则是TH0\TL0\ET0\TR0\TMOD=0X01
}
void main()
{
uchar i=0;
ld=0;
UART_Init(); // 初始化串口
LCD_Init(); // 初始化LCD
init_timer1();
while (1)
{
pwm=adc/2;
if(i<100) //输出PWM调光,将一个周期具体化为100等分,从而易得高电平多少分来计算pwm
i++;//不断自增代表对一个周期100等分中每个等分进行检查此时是高电平还是低电平。在这100中方波越疏越暗,越密越亮。
else
i=0;
if(i<pwm)
LED=0;
else
LED=1;
}
}
// 串口中断程序
void SerialInterrupt() interrupt 4 {
if (RI == 1) { // 接收到数据
cmd = SBUF; // 存储接收到的数据
if(cmd=='0')
{ld=1;}
if(cmd=='1')
{ld=0;}
RI = 0; // 清除接收中断标志
}
}
//定时器1中断函数
void Timer1() interrupt 1
{
if(time<8)
time++;
else
{
adc = ADC_read_data(0);//读取adc值
voltage = adc * 500.0 / 255;//将adc值换算成电压
LED_buffer1[4] = adc / 100 + '0'; //取adc百位
LED_buffer1[5] = adc % 100 / 10 + '0'; //取adc十位
LED_buffer1[6] = adc % 10 + '0'; //取adc个位
LED_buffer2[8] = voltage / 100 + '0'; //取电压个位
LED_buffer2[9] = '.';//小数点
LED_buffer2[10] = voltage / 10 % 10 + '0'; //取电压十分位
LED_buffer2[11] = voltage % 10 + '0'; //取电压百分位
LCD_ShowString(1, 1, LED_buffer1); //显示字符串
LCD_ShowString(2, 1, LED_buffer2); //显示字符串
}
TH0 = 0x3C; // 设置定时器1计数初值,用于控制LED亮度的PWM值
TL0 = 0xB0; // 设置定时器1计数初值,用于控制LED亮度的PWM值
}
|