![]() |
發布時間: 2022-7-9 12:03
正文摘要:在學習C語言過程中軟件的使用,為什么課本上或者自學視頻上的C語言用visual C++6.0或者visual studio系列軟件來編寫,編譯?而我們實際上的一些應用,例如,LED流水燈,呼吸燈的程序,這些程序的編寫編譯用keilx系列 ... |
zhxiufan 發表于 2022-7-19 20:12 你這個例子舉得不好,單片機的printf可以通過重定向讓數據顯示在屏幕上、通過串口發送、通過spi發送等等都能實現,而pc上面,printf也可以通過修改printf的實現,將數據通過串口、usb等發送出去 |
說的挺好,不過細節挺多的 |
說的都有啟發啊 |
可以這樣說嗎,c是語言,keil是環境? |
玩單片機 得有這個單片機的規格書(原理),學習標準C的目的 是讓你初步了解語法(邏輯能力),以及C語句執行后的狀態,比如循環,分支,賦值;便于調試的話,需要理解一點點匯編的知識。通過看LIST文件 觀看你的C語句是否被編譯。有些時候你的C語句被編譯后 可能不是你需要的狀態 |
C語言是只是工具,選一個項目,深入了解就知道一系列東西了。 |
木示 發表于 2022-7-20 19:36 TF0為什么要清零? |
Y_G_G 發表于 2022-7-20 11:48 寄存器清零 |
木示 發表于 2022-7-20 08:53 3.2==1 這應該是P3^2,不是3.2,你的修改只是修改了錯誤提示而已,不代表你的代碼是符合你的邏輯要求的 還有,有中斷中的這個TF0=1;是什么意思? |
C語言是工具。你學會了用斧子,你是用來砍樹還是用來釘釘子都可以。 |
也有人用visual C++6.0或者visual studio來寫單片機程序,當比較麻煩就是了 |
移植程序,要看DATASHEET,看有哪些可用的端口,頭文件要改一下, |
感謝各位大神的指導。現在編譯沒有問題了,不知道實際應用怎么樣。這里弄錯了是想使用3.2這個腳位的,void key_scan2() { if(3.2==1) 改成INT0就沒有再報錯了。 |
這么說吧,你學了C語言,一般的單片機 比如STM32之類的程序你能看懂功能邏輯,但是不知道為什么這么做,而如果你剛好也學習了STM32,那你就能用你的C語言結合這款硬件平臺,去實現他能夠實現的功能 |
C51雖然也是C語言,但與標準的C(基于X86)還是有很大區別的。庫函數里面很多是同名而意不同的,比如printf函數,C51是將數據通過串口發送出去,標準C是顯示在屏幕上。還有很多函數也是如此。 |
我的改動代碼如下:(以上的代碼皆是本論壇的壇友的,只作學習使用!) #include<reg52.h> #define uchar unsigned char// #define uint unsigned int// uint key2_time_cnt;// uchar key2_lock;//° uchar key2_num_s;// uchar key2_touch_s_flag;// uint shuzi;// uchar SYS1MS;// void PORT_init() // { PCON=0X00; TCON=0;// IE0=0;// TF0=1;// EA=1;// TH0=9;// } void key_scan2() { if(3.2==1)// { key2_lock=0;// key2_time_cnt=0;// if(key2_touch_s_flag==1)// { key2_touch_s_flag=0;// key2_num_s++;// if(key2_num_s>3)key2_num_s=0;// } } else if(key2_lock==0)// { key2_time_cnt++;// if(key2_time_cnt>149)// { key2_touch_s_flag=1;// key2_time_cnt=0;//Ç key2_lock=1;// } } } void key_service2() { switch(key2_num_s) { case 0: T1=1; T0=0; //key2_num_s=0; break; case 1: T1=0; T0=1; //key2_num_s=0; break; case 2: T1=1; T0=1; // key2_num_s=0; break; case 3: T1=0; T0=0; //key2_num_s=0; break; } } void main() { PORT_init(); while(1) { if(SYS1MS==1) { SYS1MS=0; key_scan2(); } key_service2(); } } void exint0() interrupt 0 //¶¨ê±Æ÷0ÖD¶Ïoˉêy { if((IE0&TF0)==1)// { IE0=0;// TF0=0;// TH0=9;// shuzi++; if(shuzi==4) { shuzi=0; SYS1MS=1; } TF0=1;// } } |
錯誤的提示如下: |
木示 發表于 2022-7-19 17:17 看錯誤提示! |
木示 發表于 2022-7-19 17:17 怎么可能嘛兄弟 單片機和C語言是兩個知識點,兩個都要學的 學習單片機最忌諱的就是把別人的一堆代碼下載下來,想看一下效果,都驗證點什么 單片機不是這樣學的,要一步一個腳印,一點一點來的至于你想"移植",那是受了C語言簡介中的"C語言可移植性好"影響 8051和PIC是兩個不同指令的單片機的,端口名稱都中不一樣的 8051叫P0,P1........... PIC叫PA,PB............ 兩者中斷機制也是不一樣的 8051有各個中斷對應的中斷入口的,中斷程序只要觸發了就會直接執行對應的中斷 而PIC只有一個中斷入口,中斷觸發之后要先查詢中斷標志位,用來判斷是哪個中斷,然后才執行對應的中斷 8051的端口是雙向的,只要釋放了端口,直接就是可以讀取電平也可以輸出電平 而PIC在讀取的時候要先把端口設定成數據輸入模式才能讀取到端口的電平狀態 如果要輸出高低電平,那就要把端口設定成數字輸出模式,才能輸出電平 8051只要安裝了KEIL和STC下載器就可以開始學習了,可以用232下載 PIC就不一樣了,你要先安裝JAVA運行環境,安裝MPLAB,還得安裝編譯器,而PIC的又有好幾個編譯器,每個編譯器的函數都是不一樣的,完還得用專用的PICKIT下載器才能下載程序 是不是對我上面的話一臉的蒙,這就對了,在你還沒有真正入門之前,不要學PIC,除非有人帶,或者是學校教材是這樣的,又或者是工作需要 給你看一下我的第一個8051C程序,別想著一下子就能飛,你得先學會爬,然后再學會走路,走得快了,你自然就能飛了 #include<reg52.h> //包含頭文件,頭文件中有8051單片機的特殊寄存器地址的定義 sbit LED=P0^0; //用sbit關鍵字來定義LED這個端口的地址,LED方便記憶,P0這個已經在reg52.h中聲明過了,可以直接P0這個名稱 void main () { P0=0x00; //P0端口先低電平,因為默認上電為高電平 LED=1; //LED為高電平,LED亮或者滅要看硬件電路 while(1) //while循環為真,一直循環 { } } |
用單片機為PIC16F676,RA5上的腳作為交流檢測腳。RC2,RC3作為負載輸出控制端。程序如下: #include<pic.h> __CONFIG(0X1B4); #define uchar unsigned char//宏定義,相當于uchar=unsigned char #define uint unsigned int//宏定義,相當于uint=unsigned int uint key2_time_cnt;//按鍵去抖計數器 uchar key2_lock;//按鍵有效標志 uchar key2_num_s;//功能散轉變量 uchar key2_touch_s_flag;//交流斷電信號有效標志 uint shuzi;//時標計數變量 uchar SYS1MS;//時標開關標志 void PORT_init() { ANSEL=0X00;//普通端口設置 CMCON=0X07;//比較器關閉 TRISA=0b00110100; TRISC=0b00110000; PORTC=0X00; PORTA=0X00; T0CS=0;//定時器內部時鐘選擇 ; T0IF=0;//定時器中斷標志清零 T0IE=1;//定時器中斷使能 GIE=1;//全局中斷使能 TMR0=9;//定時器初值為零 } void key_scan2() { if(RA5==1)//如果RA5上按鍵沒有按下 { key2_lock=0;//2號鍵標志清零 key2_time_cnt=0;//去抖計數器清零 if(key2_touch_s_flag==1)//如果交流斷電信號有效 { key2_touch_s_flag=0;//清交流信號標志 key2_num_s++;//功能號開始自加 if(key2_num_s>3)key2_num_s=0;//一共4種功能 } } else if(key2_lock==0)//如果有鍵第一次按下 { key2_time_cnt++;//去抖計數器開始計數 if(key2_time_cnt>149)//當計數器值大于149,說明低電平持續的時間大于10MS,而交流電高低電平的持續時間是8——10MS,這就表示交流電被斷電了。 { key2_touch_s_flag=1;//交流斷電有效,標志置一。 key2_time_cnt=0;//清去抖動計數器 key2_lock=1;//自鎖標志置1,避免一直觸發 } } } void key_service2() { switch(key2_num_s) { case 0: RC2=1; RC3=0; RA0=0; RA1=0; //key2_num_s=0; break; case 1: RC2=0; RC3=1; RA0=0; RA1=0; //key2_num_s=0; break; case 2: RC2=1; RC3=1; RA0=0; RA1=0; // key2_num_s=0; break; case 3: RC2=0; RC3=0; RA0=0; RA1=0; //key2_num_s=0; break; } } void main() { PORT_init(); while(1) { if(SYS1MS==1) { SYS1MS=0; key_scan2(); } key_service2(); } } void interrupt isr()//定時器0中斷函數 { if((T0IE&T0IF)==1)//判斷定時器中斷 { T0IF=0;//清定時器中斷標志 T0IE=0;//關定時器中斷 TMR0=9;//從9加到256所用時間是250US shuzi++; if(shuzi==4) { shuzi=0; SYS1MS=1; } T0IE=1;//開定時器中斷 } } 本程序對于斷電檢測使用了 if() { 第一區 } else if() { 第二區 } 一開始,信號高電平階段,在第一區,要把各種標志清零,同時,要判斷斷電標志是否有效,這樣做的目的是為了消除,交流電斷電瞬間單片機會出現誤動作(閃燈) ,如果作為一般按鍵檢測的話,這里做判斷,并且做出相應的按鍵有效處理,實際上是,等待按鍵松手后才做有效的處理。當有低電平到來時,實際上 else if(key2_lock==0)這語句等同于else if((!RA5)&&(!key2_lock)),RA5為低,同時按鍵標志沒有被置1,確定上面2個條件同時成立,說明RA5端口起碼是低電平了,但不一定是斷電了。在第二區,然后讓去抖動計數器key2_time_cnt自加,當計數器大于149時候,認為斷電了(因為在一個周期內交流電低電平持續時間大概是100,所以要適當加寬低電平判斷范圍,)此時要馬上把斷電有效標志key2_touch_s_flag置1。 對于交流電斷電檢測功能函數key2_scan()在整個程序的位置,第一,可以直接放到定時器中斷里面,每250US執行一次。第二,可以利用定時器設定一個時標比如1MS的時標,主程序中,根據時標來執行key2_scan()函數。最好不要直接放在主循環中,這樣會漏掉按鍵檢測的某個檔位。 以上就是數碼分段器的基本控制程序。單片機交流檢測是本程序的難點。 以上是版主的代碼 |
木示 發表于 2022-7-14 17:21 C語言只是一門語言而已 就是C51也只是一門語言而已 這中斷,定時器是單片機方面的知識,不是語言方面的知識,所以說你要知道單片機的原理呀 手頭上要有兩本書,一本是單片機原理的,一本是C語言的 C語言程序設計:現代方法這本C語言的書感覺還可以,比譚老那本好多了 而8051的單片機書就多了,隨便找一本就是了,沒有誰比誰好多少 |
木示 發表于 2022-7-14 17:21 你這個問題就跟c語言無關了,要先學會畫流程圖。 |
嵌入式開發中在實際應用中,處處都會用到C語言,打印Hello Word,只是為了,看到實驗現象 |
即便學了C51單片機,也只是知道(或者稱之為理解)單個的程序思維。例如簡單的,點亮LED燈,跑馬燈這些,單個來說不難。但是如果我要把它們弄到一個程序上面來跑,比如:先亮燈,然后按下開關關閉5S內重新打開,接著跑跑馬燈程序,若超過5S后開則停留在亮燈程序上來。很多新手就懵逼了,不知道怎么運用外部中斷,定時器去上面跑。怎么把一些單個的程序,變成一個整體程序去跑? |
不一定會 發表于 2022-7-12 10:46 是的,差別還是大,比如說外部中斷,定時器,這些在標準C語言里沒有提及,但在實際應用中是十分廣發的, |
51單片機使用的C語言叫C51,擁有C語言大部分的特征,并針對51單片機進行了一部分改進,以適應51單片機的硬件開發,所以叫做C51。 C51編寫的源程序,是一個后綴為.c的C語言文件,編譯以后的運行文件是后綴為.hex的文件。 標準C語言跟單片機的C51還是有細微差別的。 |
c語言只是一個軟件語言 |
木示 發表于 2022-7-10 18:47 標準C就標準C,沒有關系的 但如果你是要用在單片機方面,你要學的就是單片機原理了 |
各位的高見十分受益,感謝! 現在市面上大部分的教材,或者視頻都是從標準的C語言著手,距離實際應用還是有相當的知識要學習. |
都曾有過類似問題,試著回答一下,不知是否切題。 1.首先得了解“編譯器,集成開發環境(IDE)”相互聯系,但不是一個東西。 2.C語言是一種高級語言,要被編譯器軟件編譯為某一特定cpu的機器碼才能運行。 VC,VS都是在pc上的集成開發環境,其內嵌編譯器可編譯X86處理器的win32、console等類型的應用程序。 Keil等集成開發環境在PC上運行,但使用不同的內嵌編譯器,用于編譯C51、ARM_M0等cpu的程序。 3.大學學的C語言,只是通用開發能力的基礎,距離實際開發還有太多的內容要學,慢慢來。 4.我理解,沒有“單片機的C語言”,只是用C開發產品級的單片機程序,需要對編譯后的內存狀態等內容了解的多一些,而且與win程序開發的常用語句有較大區別。 |
木示 發表于 2022-7-9 21:23 C和單片機C語言(比如C51)之間并沒有很大的區別,如果你是工業應用,直接學單片機C語言,就可以了 這兩者之間并不是說就是兩種語言,無非就是增加了一些或者減少一些關鍵詞之類 也就是說,隨便學哪個C語言,只要是C語言就可以了,不同領域之間的C語言,你只要幾天,或者幾個小時就能上手了,不用怕"我學了標準,到時候再學單片機的話,又得學一單片機C語言?" |
主要看你在什么芯片上運行程序, 決定了用什么編譯工具。 Vs編譯時候根本沒得選芯片 默認在PC芯片上。 keil里面可以選各種單片機。 因為這些芯片內核指令集不一樣 所以不能用同一個軟件去編譯。 |
不是學會C語言就能開發實際產品的。 |
Y_G_G 發表于 2022-7-9 18:42 這樣理解起來的話,其實除了學C語言之外,如果真的要在電子工業中應用的話,還是需要再去學單片機C語言? |
Y_G_G 發表于 2022-7-9 18:42 c語言是為了更方便的操作硬件,從而實現Unix內核而設計的,這樣的結構天生就適應單片機。 |
一個是標準C語言,visual studio"Hello,the Word"是標準V語言的,實在不理解,你就當這是電腦C語言 一個是單片機C語言,keil是單片機C語言,專門為單片機準備的,C語言一開始就不是為單片機準備的 C語言我只用在單片機,其它地方沒用過,也不會用 |
單片機c語言如果涉及到復雜的算法我也會在MinGW上面模擬運行,比單片機方便多了,調試通過直接移植到單片機c語言上面。 |