开头还是那句话
哪怕梦想让我们拼的遍体鳞伤!这一次我们也要勇往直前!
想做一个小装置 先做第一步显示模块

没放P3那个上拉电阻 p3和s8050之间也没加限流电阻 。
R11 随便找了一个 电位器
A和vcc加了一个限流电阻 也不知道有没有必要。
因为不知道 lcd1602里面有没有集成限流电阻 所以我自己就加了一个 不过看别人都没加。。。
vcc和gnd之间没有加电容
还发现一个问题 整套系统连接 电脑usb口供电可以正常运行 但是单独连接手机的充电头就行不。。不知道为啥
还有个问题 单片机不能 自动下载 每次都要在电脑上点了下载之后 在按P32 在按重启 才能下载成功。。。
视频效果
代码如下
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
sbit LCD1602_EN=P0^4;
sbit LCD1602_RS=P0^5;
sbit LCD1602_K=P0^6;
sbit LCDdata4 =P0^3;
sbit LCDdata3 =P0^2;
sbit LCDdata2 =P0^1;
sbit LCDdata1 =P0^0;
void LCD1602_WriteCmd(u8 cmd_data);//写入命令数据
void LCD1602_WriteData(u8 cmd_data);//写入显示用数据
void LCD1602_init(void);//初始化
void LCD1602_clear(void);//清屏指令 清除之前缓存的数据
void LCD1602_show_string(u8 x,u8 y,u8 *str);//x=0-15,y=0-1,str 是字符串变量
void Delay1ms(void); //@24.000MHz
void Delay500ms(void); //@24.000MHz
void main(void)
{
WTST =0;//设置程序指令延时参数
EAXFR =1;//扩展寄存器(XFR)访问使能
CKCON=0;//提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为推双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
usb_init();
IE2 = 0x80; //sub允许中断
EA = 1; //总中断
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
while(1)
{
LCD1602_init();//初始化
LCD1602_show_string(0,0,"stcaimcu");//x=0-15,y=0-1,str 是字符串变量
LCD1602_show_string(0,1,"AI8051U");//x=0-15,y=0-1,str 是字符串变量
LCD1602_K = 0;
Delay500ms();
LCD1602_K = 1;
Delay500ms();
// if (bUsbOutReady)
// {
// // USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
//
// printf("stc 真的很棒 \r\n");
//
// usb_OUT_done();
// }
//
}
}
void Delay1ms(void) //@24.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
_nop_();
i = 5998UL;
while (i) i--;
}
void Delay500ms(void) //@24.000MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 61;
j = 225;
k = 62;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void LCD1602_WriteCmd(u8 cmd_data)//写入命令数据
{
u8 i;
LCD1602_RS=0;//命令模式
LCD1602_EN=0;//使能管脚
for(i=2;i>0;i--)
{
LCDdata4 = cmd_data & 0x80;
LCDdata3 = cmd_data & 0x40;
LCDdata2 = cmd_data & 0x20;
LCDdata1 = cmd_data & 0x10;
LCD1602_EN=1;//上升沿发射数据
Delay1ms();
LCD1602_EN=0;//产生下降沿
Delay1ms();
cmd_data = cmd_data << 4;
}
}
void LCD1602_WriteData(u8 cmd_data)//写入显示用数据
{
u8 i;
LCD1602_RS=1;//数据模式
LCD1602_EN=0;//使能管脚
for(i=2;i>0;i--)
{
LCDdata4 = cmd_data & 0x80;
LCDdata3 = cmd_data & 0x40;
LCDdata2 = cmd_data & 0x20;
LCDdata1 = cmd_data & 0x10;
LCD1602_EN=1;//上升沿发射数据
Delay1ms();
LCD1602_EN=0;//产生下降沿
Delay1ms();
cmd_data = cmd_data << 4;
}
}
void LCD1602_init(void)//初始化
{
LCD1602_WriteCmd(0x28);//功能设定 8位数据总线 显示两行 5*7点阵
LCD1602_WriteCmd(0x0c);//开启显示 不显示光标 光标闪烁
LCD1602_WriteCmd(0x06);//模式设置 光标后移 屏幕不动
LCD1602_WriteCmd(0x01);//清屏指令 清除之前缓存的数据
}
void LCD1602_clear(void)//清屏指令 清除之前缓存的数据
{
LCD1602_WriteCmd(0x01);
}
void LCD1602_show_string(u8 x,u8 y,u8 *str)//x=0-15,y=0-1,str 是字符串变量
{
u8 i=0;
if(x>15|y>2) return;//超出显示范围
if(y<1)//第一行
{
while(*str!='\0')
{
if(i+x<16)//判断是字符串是否再第一行显示
{
LCD1602_WriteCmd(0x00+0x80+x+i);//写入第一行显示字符的位置命令
//0x00 就是第一行的起始偏移值 当然可以不写
//因为显示的DDRAM地址第一行是 00到0F
}
else
{
LCD1602_WriteCmd(0x40+0x80+x+i-16);//写入第二行显示字符的位置命令
//减去16就是 减去上一行的字符数
}
LCD1602_WriteData(*str);//指针取出 这个位置字符串对应的 字符
str++;
i++;
}
}
else//直接在第二行显示数据的情况
{
while(*str!='\0')
{
if(i+x<16)//判断是字符串是否再一行显示
{
LCD1602_WriteCmd(0x40+0x80+x+i);//写入第二行显示字符的位置命令
}
else
{
LCD1602_WriteCmd(0x00+0x80+x+i-16);//写入第一行显示字符的位置命令
//减去16就是 减去上一行的字符数 也就是第二行的字符数
}
LCD1602_WriteData(*str);//指针取出 这个位置字符串对应的 字符
str++;
i++;
}
}
}