![]() ![]() ![]() ![]() ![]() |
本帖最后由 yjx189 于 2016-4-16 11:05 编辑 上面的代码中,传感器使用了A0和D2口,但是这个D2口1602屏也要使用,怎么才能避开呢? 还有就是,也没有看到初始化1602屏的语句啊? |
baofu 发表于 2016-4-15 18:38 有时间的话,还请你帮我看看下面的源代码,可以用吗?费心了,朋友! PM2.5检测器 代码如下: int measurePin = 0; // 连接模拟口0 int ledPower = 2; // 连接数字口2 int samplingTime = 280; int deltaTime = 40; int sleepTime = 9680; float voMeasured = 0; float calcVoltage = 0; float dustDensity = 0; void setup(){ Serial.begin(9600); pinMode(ledPower,OUTPUT); } void loop(){ digitalWrite(ledPower,LOW); //开启内部LED delayMicroseconds(samplingTime); // 开启LED后的280us的等待时间 voMeasured = analogRead(measurePin); // 读取模拟值 delayMicroseconds(deltaTime); // 40us等待时间 digitalWrite(ledPower,HIGH); // 关闭LED delayMicroseconds(sleepTime); // 0 - 5V mapped to 0 - 1023 integer values // recover voltage calcVoltage = voMeasured * (5.0 / 1024.0); //将模拟值转换为电压值 dustDensity = 0.17 * calcVoltage - 0.1; //将电压值转换为粉尘密度输出单位 Serial.print(“Raw Signal Value (0-1023): ”); Serial.print(voMeasured); Serial.print(“ - Voltage: ”); Serial.print(calcVoltage); Serial.print(“ - Dust Density: ”); Serial.println(dustDensity); // 输出单位: 毫克/立方米 delay(1000); } |
baofu 发表于 2016-4-15 18:38 再一次表示感谢!但我弄半天还是不行!都有些烦了,过两天再说吧,再不行,就找个做程序员的朋友帮我写一个吧! |
怎么感觉这个电路很简单 |
yjx189 发表于 2016-4-15 08:05 30楼的函数digitalWrite()由于你没有贴出来函数体。只能说31楼的代码,这个应当是正确的,唯一不足就是init()函数中的: LCD_write_command(0x38); // - - 设置8位格式,2行,5x7 LCD_delay_10us(5); 只有一次写入0x38,如果这一次失败,往下就不行了。应当重复延时多次才可靠。我记得这是文档上特意说明的, 问题是为什么非得这样才可靠?我估计是1602控制器里面由于某种原因,反应太慢,需要多次重复才能建立稳定状态。纯属臆测,未必正确。 除了上述不同,与我贴出的代码很接近,而我实验是成功的,你用这个如果还不行,就应当从别处找问题了。 |
这个也写进去过: # define LCD_DB P0 // - - P0 = DB0~DB7 sbit LCD_RS=P2^0; // - - p2.0 = RS sbit LCD_RW=P2^1; // - - p2.1 = RW sbit LCD_E=P2^2; // - - p2.2 = E // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - 定义函数 # define uchar unsigned char # define uint unsigned int // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - 定义子程序函数 void LCD_init(void); // - - 初始化LCD1602函数 void LCD_write_command(uchar command); // - - 向LCD1602写指令函数 void LCD_write_data(uchar dat); // - - 向LCD1602写数据函数 void LCD_set_xy(uchar x,uchar y); // - - 设置LCD1602显示位置 X(0-16),y(1-2) void LCD_disp_char(uchar x,uchar y,uchar dat); // - - 在LCD1602上显示一个字符 void LCD_disp_string(uchar X,uchar Y,uchar *s); // - - 在LCD1602上显示一个字符串 //void LCD_check_busy(void);//检查忙函数。我没用到此函数,因为通过率极低。 void LCD_delay_10us(uint n); // - - 10微秒的延时子程序 void LCD_delay_50us(uint n); // - - 50微秒的延时子程序 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - 初始化LCD1602 void LCD_init(void) { LCD_delay_10us(20); LCD_write_command(0x38); // - - 设置8位格式,2行,5x7 LCD_delay_10us(5); LCD_write_command(0x0c); // - - 整体显示,关光标,不闪烁 LCD_delay_10us(5); LCD_write_command(0x06); // - - 设定输入方式,增量不移位 LCD_delay_10us(5); LCD_write_command(0x01); // - - 清除屏幕显示 LCD_delay_50us(40); } //******************************** // - - 向LCD1602写指令 void LCD_write_command(uchar dat) { LCD_delay_10us(5); LCD_RS=0; // - - 指令 LCD_RW=0; // - - 写入 LCD_DB=dat; LCD_delay_10us(5); LCD_E=1; // - - 允许 LCD_delay_10us(5); LCD_E=0; } // - - 向LCD1602写数据 void LCD_write_data(uchar dat) { LCD_delay_10us(5); LCD_RS=1;// - - 数据 LCD_RW=0;// - - 写入 LCD_DB=dat; LCD_delay_10us(5); LCD_E=1;// - - 允许 LCD_delay_10us(5); LCD_E=0; } // - - 设置显示位置 void LCD_set_xy(uchar x,uchar y) { uchar address; if(y==1) { address=0x80+x; // - - 第一行位置 } else { address=0xc0+x; // - - 第二行位置 } LCD_delay_10us(5); LCD_write_command(address); } // - - 显示一个字符函数 void LCD_disp_char(uchar x,uchar y,uchar dat) // - - LCD_disp_char(0,1,0x38); // - - 显示8 { LCD_set_xy(x,y); LCD_delay_10us(5); LCD_write_data(dat); } // - - 显示一个字符串函数 void LCD_disp_string(uchar x,uchar y,uchar *s) { LCD_set_xy(x,y); LCD_delay_10us(5); while(*s!='\0') { LCD_write_data(*s); s++; } } //******************************** /*******检查忙函数************* void LCD_check_busy() //实践证明,在我的LCD1602上,检查忙指令通过率极低,以 { //至于不能正常使用LCD。因此我没有再用检查忙函数。而使 do //用了延时的方法,延时还是非常好用的。我试了一下,用 { LCD_E=0; //for循环作延时,普通指令只要1次循就可完成。清屏指令 LCD_RS=0; //要用200次循环便能完成。 LCD_RW=1; LCD_DB=0xff; LCD_E=1; }while(LCD_DB^7==1); } void LCD_delay_10us(uint n) // - - 10微秒的延时子程序 { uint i,j; for(i=n;i>0;i--) for(j=2;j>0;j--); } void LCD_delay_50us(uint n) // - - 50微秒的延时子程序 { uint i,j; for(i=n;i>0;i--) for(j=22;j>0;j--); } |
baofu 发表于 2016-4-14 19:53 谢谢你的热心帮助!我的写的代码如下(在网上搜到的),有空请帮我找找问题! int LCD1602_RS=12; int LCD1602_RW=11; int LCD1602_EN=10; int DB[] = { 6, 7, 8, 9}; char logtxt[]="Local Time"; char *sec[60]={"00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59"}; void LCD_Command_Write(int command) { int i,temp; digitalWrite( LCD1602_RS,LOW); digitalWrite( LCD1602_RW,LOW); digitalWrite( LCD1602_EN,LOW); temp=command & 0xf0; for (i=DB[0]; i <= 9; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; } digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW); temp=(command & 0x0f)<<4; for (i=DB[0]; i <= 9; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; } digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW); } void LCD_Data_Write(int dat) { int i=0,temp; digitalWrite( LCD1602_RS,HIGH); digitalWrite( LCD1602_RW,LOW); digitalWrite( LCD1602_EN,LOW); temp=dat & 0xf0; for (i=DB[0]; i <= 9; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; } digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW); temp=(dat & 0x0f)<<4; for (i=DB[0]; i <= 9; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; } digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW); } void LCD_SET_XY( int x, int y ) { int address; if (y ==0) address = 0x80 + x; else address = 0xC0 + x; LCD_Command_Write(address); } void LCD_Write_Char( int x,int y,int dat) { LCD_SET_XY( x, y ); LCD_Data_Write(dat); } void LCD_Write_String(int X,int Y,char *s) { LCD_SET_XY( X, Y ); //设置地址 while (*s) //写字符串 { LCD_Data_Write(*s); s ++; } } void setup (void) { int i = 0; for (i=6; i <= 12; i++) { pinMode(i,OUTPUT); } delay(100); LCD_Command_Write(0x28);//4线 2行 5x7 delay(50); LCD_Command_Write(0x06); delay(50); LCD_Command_Write(0x0c); delay(50); LCD_Command_Write(0x80); delay(50); LCD_Command_Write(0x01); delay(50); } void loop (void) { for(int index=0,minindex=59,hourindex=12;index<60;index++) //这里来设定现在时间,目前设定为12:59:00 { LCD_Command_Write(0x01); delay(50); LCD_Write_String(3,0,logtxt); LCD_Write_String(3,1,sec[hourindex]); LCD_Write_Char(6,1,0x3a);//显示: LCD_Write_String(7,1,sec[minindex]); LCD_Write_Char(10,1,0x3a); LCD_Write_String(11,1,sec[index]); delay(950); if (index==59) { index=-1; minindex++; if (minindex==60) { minindex=0; hourindex++; if (hourindex==24) { hourindex=0; } } } } } |
Action 发表于 2016-4-14 14:20 我邮箱,yjx189@sohu.com,谢谢! |
本帖最后由 baofu 于 2016-4-14 20:01 编辑 我用的单片机与你不一样,管脚什么都不一致,HEX文件给你也无法用。比较合适的办法是你把你的初始化部分的代码贴在这里,大家共同找找问题。我的代码很简单: void LCD_init() { LCD_delay_50us(20); LCD_RS=0; // - - 指令 LCD_RW=0; // - - 写入 LCD_E=0; // - - 使能 LCD_write_L4bit_command(0x38); //写0x38 LCD_delay_50us(2); //延时 LCD_write_L4bit_command(0x38); //重复写 LCD_delay_50us(10); //延时 LCD_write_L4bit_command(0x38); // 重复写 LCD_delay_50us(5); 延时 LCD_write_L4bit_command(0x38); // LCD_delay_50us(10); //可靠的初始化主要就是上面几行 LCD_write_L4bit_command(0x02); // LCD_delay_50us(2); LCD_write_4bit_command(0x28); // - - LCD_delay_10us(10); LCD_write_4bit_command(0x0c); // - - 整体显示,关光标,不闪烁 LCD_delay_10us(10); LCD_write_4bit_command(0x06); // - - 设定输入方式,增量不移位 LCD_delay_10us(10); LCD_write_4bit_command(0x01); // - - 清除屏幕显示 LCD_delay_50us(40); } |
不懂 ![]() |
给我邮箱 我给你发程序 你这个的主要原因是 需要把vee接到滑动变阻器的滑动脚 滑动变阻器其他两个脚接电源跟地 调节滑动变阻器就可以了 |
第三个问题,可以用定时 |
看看大神如何解决 |
我已经用单片机往1602里写了,但还是那样,问题还是没得到解决! |
网上看看1602的历程,对比看看 |
本帖最后由 yjx189 于 2016-4-14 08:14 编辑 baofu 发表于 2016-4-14 08:02 |
baofu 发表于 2016-4-13 20:01 能否把你写的初始化程序给我复制一份,我参考一下使用?谢谢了! |
yjx189 发表于 2016-4-13 21:40 1602自己不能接受写入程序,也写不进去,只能用单片机对1602进行写命令或写数据。 |
不是往1602里面写程序,它也不能接收。1602只能与单片机之间交换数据。初始化也是单片机对1602操作才能完成。 |
1602里面主要是液晶点阵,这些点阵受控制器的指挥,而控制器又受单片机的指挥。单片机对控制器只有三种操作:查忙;写命令;写数据;所有的这些都是单片机对1602的操作,所以不用往1602写程序,也写不进去。 查忙:控制器工作比单片机慢,操作前先查忙,答复有空闲才能真的操作。为了简单,往往就用延时取代了。 写命令:所有的命令都是十六进制数,具体含义要查厂方的文档。比如上述写0x38,是设置显示模式命令。 写数据:写入要显示的内容。 |
wc86110 发表于 2016-4-13 22:41 明白了,谢谢!我正在网上找有关资料,学习烧写1602初始化函数的问题! |
是往目标单片机里烧写程序而非往1602。 |
本帖最后由 yjx189 于 2016-4-13 21:41 编辑 baofu 发表于 2016-4-13 21:15 UNO是Arduino UNO开发板(相当于51单片机的开发板,这个我也有) 的简称,我是在UNO板上写好了程序,把写好程序的芯片拿下来(相当于单片机的STC89C52),做了一个最小系统板,一边接上v,传感器,做一个PM2.5的检测仪! 不过,上面说了,我也有STC89C52的开发板,可以写程序,要往1602里面写程序,是不是就是通过89C52的开发板(插上1602屏)往里面写初始化的程序啊? |
本帖最后由 yjx189 于 2016-4-14 10:05 编辑 UNO是Arduino UNO开发板(相当于51单片机的开发板,这个我也有) 的简称,我是在UNO板上写好了程序,把写好程序的芯片拿下来(比如单片机的STC89C52),做了一个最小系统板,接上1602屏,传感器,做一个PM2.5的检测仪! |
具体对1602的操作函数,网上可以查到很多例子。 你说的UNO板子,我确实不熟悉。 从你说的看,像是自己又做了一个板子?如果你自己做的板子是模仿UNO而不成功,则可能你自制的板子有问题。 |
本帖最后由 yjx189 于 2016-4-15 07:20 编辑 baofu 发表于 2016-4-13 20:27 本帖最后由 yjx189 于 2016-4-13 20:35 编辑 请问: 怎么往1602里面写东西啊?在一个是:为什么我的1602和写好程序的ATMEGA328P芯片,在UNO板上,就都一切正常,到了我做的ATMEGA328P芯片小系统上,就都不正常了呢? |
本帖最后由 yjx189 于 2016-4-14 08:06 编辑 请问: 怎么往1602里面写东西啊?在一个是:为什么我的1602和写好程序的ATMEGA328P芯片,在UNO板上,就都一切正常,到了我做的ATMEGA328P芯片消息同伴上,就都不正常了呢? |
就是往1602写0x38,实际就是写设置显示模式的命令(注意模式不同,命令不一样),关键是多重复几次,且每次之间延时就行了。 |
本帖最后由 yjx189 于 2016-4-13 20:21 编辑 baofu 发表于 2016-4-13 20:01 估计就是你说的初始化的问题了!那请问:0X38要往哪里面写?怎么写呢?请明示,多谢了!(实在不好意思!我学单片机也就才20天,大学的专业也是汽车,不是电) |
baofu 发表于 2016-4-13 20:01 我是个小白,哈哈,学单片机也就才20天,并且大学的专业也是汽车,请问,是要上电前,先找个1602的初始化的程序,写进ATMEGA329P的芯片里吗? |
主要是上电后一开始就执行置显示模式命令(我的是写入0x38),至少要重复4次,且每次之间加1ms到5ms的延时(用延时就不再查询忙否了),我的实践证明,这很关键。 但平台硬件都不同,只能供你参考。 |
本帖最后由 yjx189 于 2016-4-13 19:47 编辑 baofu 发表于 2016-4-13 15:15 谢谢回复!电源是稳压供电5V。那请问:初始化不合适,怎么操作,就能合适了呢? |
我用stc12c5410ad单片机驱动1602,也有过类似于你遇到的这种情况。 1.显示方框不显示文字,基本上是两种原因:第一种是对比度调整不当,在我的屏上,就是1602的V0管脚电压不合适;你的已经正常显示过,这个可以排除。第二种是管脚接触不良,我用杜邦线连接,很容易出现连接不可靠,动动连接线就好了。 2.显示内容不对,且字符自动移动。这个多数是对1602的初始化不合适或者“忙”处理不当所致。特别是当给1602供电的电源偏低的时候,往往会导致1602初始化失败。 由于硬件不同,仅供参考。 |
现在的现象是: 一,把ATMEGA328P芯片写入“点亮一盏灯”程序,在相当于UNO板的13脚的引脚接上LED和电阻,LED闪烁正常。 二,写入“欢迎,,,,,”程序,有时1602屏能正常显示“欢迎,,”的英文,有时则只显示两行灰色的方块。 三,写入“简单时钟电路”程序,1602屏两行乱码,并且随着时钟的秒的节奏,从屏左面向平右面滚动。 四,换其他的1602屏插上,情况一样。这两个程序的芯片,插在UNO板子上,都显示正常。 请问各位高手,这是什么问题?怎样解决? |