|
![]() ![]() ![]() ![]() 很不錯的樣子 |
|
本帖最后由 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板子上,都顯示正常。 請問各位高手,這是什么問題?怎樣解決? |