前輩學51單片機的感悟是怎麼樣的?說說看

分享學習51單片機的過程經歷 一起來說說吧


從事安卓底層開發,工作一年,個人看法 ,處女答。個人感腳51就是就是搞嵌入式第一門技術。把c語言,模數電,硬體畫板等第一次聯繫起來。在學校的時候我們的學習路線是:
1 : 51單片機(大二上學期的時候,我感覺我還是接觸的挺晚的,嵌入式)
2:stm32+ucos ii (大二下學期到大三下學期)
3:Arm+linux (大四到畢業)
4.安卓驅動 ,JNI(工作,mtk平台)
然並卵,這句話適合51,但是也是非常非常非常重要的基礎。如果作為學生的話,參加比賽啥的51還是不夠用的。51作為最簡單的單片機,真真的簡單。相比於linux 安卓真的太簡單。
第一次回答知乎問題,也不知道什麼格式,我說到哪裡就是哪裡,以上一段是手機碼的,回到家中,用電腦碼字舒服多了。下面我是說到哪裡就是哪裡了。如果有啥問題歡迎評論,我會回答的,一有空。
---------------------------------------------------------------------------------------------------------------------------------------

51單片如我上文所說的,學生黨接觸的第一款單片機,答主是電子信息工程畢業的,接觸的第一個單片機也是51,然後是STM32.51和STM32 STM32比51 難一點,不過本質上都是單片機,STM32片上外設多很多,定時器啥的複雜複雜複雜複雜複雜多的多。STM32片上外設多,功能強大,可以說學了STM32之後基本上所有的單片機應該都能馬上上手的,雖然我也只是只接觸到51 和STM32.。大四全國電子設計大賽之後就再也沒有接觸到單片機了。後來就一直是linux,android。下面是我畢業論文的一部分。
---------------------------------------------------------------------------------------------------------------

任何計算機系統都是軟體和硬體的結合體,如果只有硬體而沒有軟體,則硬體是沒有靈魂的軀殼;如果只有軟體沒有硬體,則軟體就是一堆無用的字元。在底層硬體的基礎上,操作系統覆蓋一層驅動,屏蔽底層硬體的操作,通過特定的軟體介面去操作底層硬體,用戶在用戶空間可以很容易的把軟體設計目標放在策略與需求上,可以很方便的屏蔽掉底層實現,從而很好的完成客戶功能需求。計算機系統是軟體和硬體的結合體。而軟體又分為應用層軟體和驅動層軟體。驅動層軟體是應用層軟體和底層硬體的紐帶。通過驅動層軟體實現對底層硬體屏蔽。

在裸機時代,比如單片機系統,程序員往往是直接操作硬體寄存器,直接設置硬體。而在Linux操作系統中,硬體驅動程序中實現對硬體直接操作,而用戶空間,通過通用的系統調用介面,實現對硬體操作,應用程序沒有直接操作底層設備,通過posix標準,應用程序的系統調用往往是被規定和限值,用戶只能通過規定的介面實現對底層硬體的操作,導致了應用程序在類UINIX操作系統具有非常好的可移植性。

圖2.1 直接操作硬體程序

上圖2.1 是裸機時代,應用程序和硬體操作糅合在一起,應用程序和硬體操作高度耦合的框圖,上述代碼一般很難有良好的代碼互用和移植性。往往從一個平台移植到另一個平台,甚至是同一平台不同硬體配置都要求很大的代碼改動,另外從應用層來說,應用與驅動高度耦合,應用程序也幾乎難以移植,甚至說是沒有應用程序概念,原因在於應用與驅動的糾纏不清。

圖2.2 無操作系統應用程序和設備驅動程序關係

上圖2.2所示,良好的裸機代碼框架,設備驅動層和應用層之間有良好的分層思想,用戶可以較好的實現策略和需求,例如:客戶要求實現流水燈程序,程序員在底層機制實現(硬體操作)的基礎下,可以充分在用戶應用程序中把主要精力方法流水燈的實現,即策略。但是在良好的裸機程序設計,代碼移植性可能從一個平台移植到另外一平台只需要修改少量的底層驅動,例如:LED_ON()的實現。但是在用戶空間,沒有系統調用概念,函數介面千差萬別。應用程序移植性差。

圖2.3 Linux系統調用框圖

操作系統中,需求決定應用程序,通過系統調用,調用底層驅動,此外,在驅動程序中,把一部分公用的驅動介面抽象出來,如此,程序員只需修改很少量的驅動資源,形成特定的驅動框架。導致用戶只需添加專用的硬體屬性作為平台資源,在內核中獲取資源,大大解放了設備驅動開發,提高了設備驅動的通用型。在用戶空間,由於遵循posix標準,類UNIX操作系統中,所有操作介面基本一樣,從而方便了應用程序的移植,應用程序幾乎不要做修改。如圖2.3所示。

Linux操作系統對於所有的硬體都是當做一個文件來操作:一切設備皆文件。Linux設備文件一般分為字元設備,塊設備,網路設備。在Linux系統中,除了網路設備之外,所有的設備都被映射到Linux的文件系統中。如圖2.4所示。

圖2.4 Linux操作系統與應用程序關係

--------------------------------------------------------------------------------------------------------------------------------------------

講講51,linux,安卓之間的差別。先申明一下,我是實際工作中沒有使用過單片機,我使用單片機僅僅是用來參加全國電子設計大賽。工作主要在android driver這一塊。我們這一行很多人說單片機是有瓶頸的,我也不是很清楚。但是實話實說,這鳥東西太簡單了,沒啥技術含量的,你要之後android的龐大。

歡迎點贊。後面會說說android,linux,51,32單片機之間的聯繫與學習方法,雖然我也是菜鳥,如果你現在看不懂也沒關係,有個映像就行。以後就有方向去學習了。想當初我真的是一個人孤孤學習linux

===============================================================

補充一個:單片機要點亮一個led等,同樣在安卓上你點亮一個燈也要驅動的,不然怎麼亮呢,只是我們只看到了app。 背後驅動,怎麼實現的,安卓架構,跟單片機有啥區別,相同的地方。其實手機arm晶元跟單片機都是嵌入式微處理器,單片機叫做微控制器。高通,mtk啥的也是嵌入式微處理器~都是一樣的~但是難度你想想看就知道了。


51單片機大家都知道了,裸機,直接操作硬體,直觀,簡單,沒有框架,沒有系統。

STM32,可以學習一下RTOS了,實時的小系統,ucos II等等許多實時系統,STM32+ucos II這種組合學習方式還是挺好的。STM32比較難的在我印象中一個是時鐘樹,因為我們從51,沒有時鐘樹的概念12M晶振,時鐘不要你配置,而比較新的ARM框架,外設都是有時鐘的。可能剛剛接觸概念不是很清楚,但是也是很簡單的。另外一個是定時器,什麼輸入捕獲模式,定時器模式,編碼器模式。。。。。強大的多,比起51。總的來說還是簡單的。因為是沒有框架的原因,代碼量真的很少。你要知道,MTK android 5.1 所有的東西加起來 10G多,包括bootloader,linux kernel,android framework ,定製的部分。等等。我們接觸的就那些目錄,當你去看C++,java代碼時,你就知道面向過程的代碼真的很容易看。可能有些朋友不知道android的框架,以及android 與linux之間的關係,以及linux驅動與裸機的關係,聯繫與區別。你現在只要知道linux驅動比較大,android框架更大。單片機簡單。單片機一般是C語言,而android一般涉及三種語言:底層linux內核C,中間的JNI層是C++,framework和app是java。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

學過51單片機的朋友知道,我們要點亮一個LED燈,是這樣子的P0 = xxx ,我們就點亮了一個,好。一燒寫,好,燈亮了。linux,上我們要亮一個燈,有點難了,有了操作系統,沒那麼容易了。一般人搞不定了。好,到android,更加難了。但是你想一想手機晶元也是ARM。亮燈這種肯定都是CPU的管腳操作。上了系統了,難了,點個燈都費勁的。本質上是一樣的。很多人都知道單片機有瓶頸的。原因是會點硬體,會點C,輕輕鬆鬆就可以亮燈的。入門容易。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

我舉一個小的例子說明一下51,linux,android三者的之間的差別。你就知道是啥區別。下面是51單片機:

大概是這樣:

int main(void) //一個main函數 搞定
{
P0 = 0xxx;
while(1);
return 0;
}

linux:

驅動程序:
#include& #include& #include& //file_operatios
#include& //class_create/device_create
#include& //kmalloc
#include& //ioremap
#include&
#include"led.h"

struct s5pv210_device *s5pv210_dev;

volatile unsigned long *gpc0con = NULL;
volatile unsigned long *gpc0dat = NULL;

static int led_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO"%s()-%d
", __func__, __LINE__);

/*初始化GPC0_3,GPC0_4引腳功能為輸出功能*/
*gpc0con = ~((0xf&<&<12)|(0xf&<&<16)); *gpc0con |= ((0x1&<&<12)|(0x1&<&<16)); return 0; } static int led_close(struct inode *inode, struct file *file) { printk(KERN_INFO"%s()-%d ", __func__, __LINE__); //iounmap(S5PV210_PA_GPC0CON); return 0; } static ssize_t led_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { printk(KERN_INFO"%s()-%d ", __func__, __LINE__); return 0; } //write(fd, val, 4) static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { int ret; unsigned int val; printk(KERN_INFO"%s()-%d ", __func__, __LINE__); /*獲取用戶空間數據*/ ret = copy_from_user(val,buf,count); if(ret) { printk(KERN_ERR"copy data from user failed! "); return -ENODATA; } printk(KERN_INFO"copy data from user: val=%d ",val); if(val) { //點亮LED *gpc0dat |= ((0x1&<&<3)|(0x1&<&<4)); } else { //熄滅LED *gpc0dat = ~((0x1&<&<3)|(0x1&<&<4)); } return ret?0:count; } static struct file_operations led_fops={ .owner = THIS_MODULE, .open = led_open, .read = led_read, .write = led_write, .release = led_close, }; static int __init led_init(void) { int ret; printk(KERN_INFO"%s()-%d ", __func__, __LINE__); s5pv210_dev = kmalloc(sizeof(struct s5pv210_device),GFP_KERNEL); if(s5pv210_dev==NULL) { printk(KERN_INFO"no memory malloc for s5pv210_dev! "); return -ENOMEM; } /*註冊*/ led_major = register_chrdev(0,"led",led_fops); if(led_major&<0) { printk(KERN_INFO"register major failed! "); ret = -EINVAL; goto err1; } /*創建設備文件*/ s5pv210_dev-&>led_class = class_create(THIS_MODULE,"led_class");
if (IS_ERR(s5pv210_dev-&>led_class)) {
printk(KERN_ERR "class_create() failed for led_class
");
ret = -EINVAL;
goto err2;
}

s5pv210_dev-&>led_device = device_create(s5pv210_dev-&>led_class,NULL,MKDEV(led_major,0),NULL,"led");
if (IS_ERR(s5pv210_dev-&>led_device)) {
printk(KERN_ERR "device_create failed for led_device
");
ret = -ENODEV;
goto err3;
}

/*將物理地址映射為虛擬地址*/
gpc0con = ioremap(S5PV210_PA_GPC0CON,8);
if(gpc0con==NULL)
{
printk(KERN_INFO"ioremap failed!
");
ret = -ENOMEM;
goto err4;
}
gpc0dat = gpc0con + 1;

return 0;
err4:
device_destroy(s5pv210_dev-&>led_class,MKDEV(led_major,0));
err3:
class_destroy(s5pv210_dev-&>led_class);
err2:
unregister_chrdev(led_major,"led");
err1:
kfree(s5pv210_dev);
return ret;
}
static void __exit led_exit(void)
{
printk(KERN_INFO"%s()-%d
", __func__, __LINE__);
unregister_chrdev(led_major,"led");
device_destroy(s5pv210_dev-&>led_class,MKDEV(led_major,0));
class_destroy(s5pv210_dev-&>led_class);
iounmap(gpc0con);
kfree(s5pv210_dev);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

應用程序:

#include &
#include &
#include &
#include &
#include &
#include &
#include &
#include &

/*
** ./led_test on 點亮LED
** ./led_test off 熄滅LED
*/
int main(int argc, char **argv)
{
int fd;
int val =0;
fd = open("/dev/led", O_RDWR);
if(fd&<0) { perror("open failed! "); exit(1); } if(strcmp(argv[1], "on")==0) { val = 1; } else { val = 0; } if(write(fd, val, 4)!=4) { perror("write failed! "); exit(1); } close(fd); return 0; }

android:

不知道大家清不清楚android與linux之間的關係。

android是基於linux內核的,linux操作系統的5大組件:驅動,內存管理,文件系統,進程管理,網路套接字。android是基於linux kernel上的,大家平時只看到了app。app是java語言的,其實每運行一個java應用程序,實際上是fork一個linux應用程序。android四大組件,activity,service,Broadcast Receiver,Content Provider。這是android的主要框架,java應用開發是基於這開發的。android平台是基於linux 內核的。在linux運行之後才建立起java世界。

直接上代碼:上面的linux的驅動在android是一樣的,適用於android。驅動ok之後是應用層了,也就是應用程序。我下面就是最直接的應用,不包含任何android框架性的東西,大家可以直接看到,應用app-&>jni-&>linux驅動這三層調用關係。下面是jni代碼是c++;

#define LOG_TAG "led-jni-log"
#include &

#include "jni.h"

#include &
#include &
#include &
#include &
#include &
#include &
#include &

static int fd = -1;

jint open_led(JNIEnv *env, jobject thiz)
{
LOGD("$$$%s
", __FUNCTION__);
fd = open("/dev/led1", O_RDWR);
if(fd &< 0) { LOGE("open : %s ", strerror(errno)); return -1; } return 0; } jint led_on(JNIEnv *env, jobject thiz) { LOGD("$$$%s ", __FUNCTION__); int val = 1; jint ret = 0; ret = write(fd, val, 4); if(ret != 4) { LOGE("write : %s ", strerror(errno)); return -1; } return 0; } jint led_off(JNIEnv *env, jobject thiz) { LOGD("$$$%s ", __FUNCTION__); int val = 0; jint ret = 0; ret = write(fd, val, 4); if(ret != 4) { LOGE("write : %s ", strerror(errno)); return -1; } return 0; } jint close_led(JNIEnv *env, jobject thiz) { LOGD("$$$%s ", __FUNCTION__); if(fd &> 0)
close(fd);
return 0;
}

static JNINativeMethod myMethods[] ={
{"openDev", "()I", (void *)open_led},
{"onDev", "()I", (void *)led_on},
{"offDev", "()I", (void *)led_off},
{"closeDev", "()I", (void *)close_led},
};

jint JNI_OnLoad(JavaVM * vm, void * reserved)
{
JNIEnv *env = NULL;
jint ret = -1;
ret = vm-&>GetEnv((void **)env, JNI_VERSION_1_4);
if(ret &< 0) { LOGE("GetEnv error "); return -1; } jclass myclz = env-&>FindClass("com/ledtest/LedActivity");
if(myclz == NULL)
{
LOGE("FindClass error
");
return -1;
}
ret = env-&>RegisterNatives(myclz, myMethods, sizeof(myMethods)/sizeof(myMethods[0]));
if(ret &< 0) { LOGE("RegisterNatives error "); return -1; } return JNI_VERSION_1_4; }

然後是java app:

package com.ledtest;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class LedActivity extends Activity {

final String TAG = "LedActivity";
public Button btn_on = null;
public Button btn_off = null;

public void init() {
btn_on = (Button) this.findViewById(R.id.btn1);
btn_on.setOnClickListener(clickListener);

btn_off = (Button) this.findViewById(R.id.btn2);
btn_off.setOnClickListener(clickListener);
}

OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1:
Log.d(TAG, "led on in app");
onDev();
break;
case R.id.btn2:
Log.d(TAG, "led off in app");
offDev();
break;
default:
break;
}

}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_led);
init();
openDev();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_led, menu);
return true;
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();

closeDev();
}

static {
System.loadLibrary("led_jni");
}

public native int openDev();

public native int onDev();

public native int offDev();

public native int closeDev();
}

框架是這樣的:最上層是java ,點開app,點擊一下一個button,點亮了LED,調用onDev();onDev調用c++的led_on,然後led_on是調用驅動的led_write,明白不?這樣說吧:linux 驅動是最下層的,驅動嘛。然後是c++層,c++包裝一下是給java調用的,然後到java層。下面是android比價經典的一張框架圖。

linux在最下面。lib 是動態庫。然後是JNI,然後是Framework(android框架),然後是大家喜聞樂見的app。


瀉藥
大一加實驗室、以為有了單片機就有了全世界、
大二學了數電大三學了微機原理、發現「以前學的單片機」P都不是、
//雖然自己技術也不咋地

拋開核心理論談工具都是耍流氓、

跟著常式跑幾個demo以為掌握了單片機的精髓、用什麼感測器電機功率管調調通以為就會開發了、
還是建議在跑完幾個常式以後、系統的學一下C語言數電微機原理和單片機理論、以及各種控制演算法、
對了不要全聽實驗室的人跟你說動手能力比理論知識重要、他們只是想讓你幫更多的忙、
工具可以培養你的興趣、但絕對不能取代理論、等你學完理論回頭再看工具、不管是51、32、430、甚至DSP、FPGA你都能輕鬆上手、

我現在就很後悔當初沒有人告訴我這些

------------------------------------------我是分割線----------------------------------------

一夜之間這麼多贊,之前回答手機隨手答的也比較水,決定再來扯一點。首先我要說明我自己技術真的不咋的,不然也不會有前文最後一句了,但是接觸了這麼多人這麼多課程這麼多老師以後,多少還是有點感悟的。

首先要放清51的定位,跟我一起再念一遍:51隻是個工具51隻是個工具51隻是個工具。當然51還有一個地位就是大學生單片機啟蒙教程。換句話說:單片機只是個工具單片機只是個工具單片機只是個工具。

然後什麼是基礎:模電數電微機原理、、、然後熟練翻閱數據手冊,可以試著做一些模塊或者最小系統練練手、、、C語言其實也可以算工具吧,就單片機來說,作為必要條件也算作基礎吧。

再然後是要儘早搞明白自己的專業方向或者自己準備發展的方向,然後不同方向又有不同的專業基礎,你學測控,就需要知道各種感測器的原理速度誤差、控制原理、演算法//買測量模塊用不叫測控啊喂;你學信號處理,就需要信號與系統、數字信號處理基礎,然後慢慢接觸DSP、FPGA、//信號處理真的不是result=(AD+0.5)/4096*3.3啊喂;你想做嵌入式開發,就慢慢研究ARM的架構,跑一些實時系統甚至高端ARM跑Linux開發驅動或應用;你要是想做通信,通信原理編碼論電磁場什麼的總得會吧、FPGA基帶什麼的你總得會艹吧、你還得不停讀論文跟得上現在的發展水平吧、

總之51/單片機可以實現很多事情,但這不是一定說51重要,而是你如何利用51。哦對了,當你使用更高級的晶元的時候,很多底層的東西慢慢可以忽略了,甚至很多晶元廠商都會提供庫給你,你可以安心的專註於自己的演算法而不是如何去控制單片機。當然你最好還是要有一個晶元怎麼通過寄存器及各種邏輯電路工作的概念。

大部分方向都不需要你單片機用的多麼6、除了嵌入式開發、而你現在學單片機你要搞清楚你是單純的為了做一些簡單的測量運算控制、還是要把一個系統、平台做出來作為一個嵌入式產品、真的有時候不要下太多功夫、

還有說一下你大學課餘生活的選擇、首先那種機器人實驗室或者學生領導的實驗室,適合打比賽刷獎狀、長期下來你的模數電技能能有很大的鍛煉,甚至你可以收貨一些專利,而且學生之間氣氛也還不錯。另外一種就是找個導師跟著學習、幫忙、做項目,儘管最開始可能感覺導師分配給你的任務怎麼都和單片機無關啊好無聊,但是你能在某個領域收穫不一樣的技術。當然前提是你要喜歡導師的研究方向了,一般院網站都有或者去知網看這個老師發表的論文。

總之一言難盡啊、、、這兩天忙成狗語無倫次不要管我、、、

//拿著經費報的機械鍵盤碼字真特么舒暢

------------------------------------------我也不知道分割線是幹嘛用的----------------------------------------

今天看到一篇答案,覺得說的挺好,甩鏈接:在大學本科階段學ARM有效果嗎? 目前已經熟悉了stm32,飛思卡爾等單片機,想再學一學ARM,有價值嗎? ? - 知乎用戶的回答


1、我從不說51是基礎,如果我這麼說,也請把這句話理解為微機原理是基礎


2、對51單片機的操作本質上就是對寄存器的操作,對其他單片機也是如此。只是一個介面,方便使用者使用而已。


3、彙編語言在工作中很少用到,了解就好。


4、51的P0口很特別。


5、C語言就是C語言,51單片機就是51單片機,演算法就是演算法,外圍電路就是外圍電路,感測器就是感測器,通信器件就是通信器件,電路圖就是電路圖,PCB圖就是PCB圖,模擬就是模擬。

當你以後再也不使用51了,C語言的知識還在,演算法的知識還在,搭建單片機的最小系統的技能還在,感測器和通信器件的使用方法還在,還會畫電路圖和PCB圖,當然也會模擬。


6、51單片機是這個:

而不是這個:

7、當程序調試不如人意的時候,靜下心來好好查資料,51單片機最大的好處就是網上資料非常多,你遇到的問題別人肯定也遇到過。作為學習者,問人可能更方便點,但一直這樣是培養不出解決問題的能力的。


8、有些單片機初學者覺得看常式不好,覺得就等於看答案一樣有罪惡感。其實對初學者來說,看常式理解常式再看常式的註解是最好的學習途徑。做實驗做課程設計做參賽作品的時候也是可以移植程序的,不需要自己重新實現。(當然老師布置的作業還是獨立完成好)

但是,要清楚,移植程序不等於學習單片機,最重要的是知道常式是怎樣的框架及實現方法。初始化了哪些寄存器,做了哪些引腳配置,調用了哪些函數,那些函數又是怎麼實現的,設置了哪些中斷,用到了哪些片上資源(UART、ADC等),查詢了哪些狀態,如果狀態變化(觸發事件)又會做些什麼等等。由此整理出一個流程圖並知道其實現方式,基本上這個常式就學習得差不多了。
(2016-03-29 補充)

∞、想到再補


我又來裝逼了,千萬不要攔著我!!!!
@閼男秀首先艾特男神,男神說的很贊,51單片機

1、我從不說51是基礎,如果我這麼說,也請把這句話理解為微機原理是基礎

2、對51單片機的操作本質上就是對寄存器的操作,對其他單片機也是如此。只是一個介面,方便使用者使用而已。

這句話更好的擴充應該是51單片機畢竟只是一個工具,任何沉迷於某一種特定工具的行為都是在耍流氓!!!
51其核心價值在於低廉的價格,適中的性能(STC現在的性能越來越BT了),能很好的應用於工業的種種場合。最常見的就是工業控制~
那麼,工業控制,就會涉及各種花式控制演算法的考慮,PID,FIR,IIR等基礎演算法,還有各種結合了高級演算法的實現,比如花式神經網路PID,遺傳退火PID,自適應濾波等等(這特么的都是什麼啊,摔
可以參考這個
哪些控制類的演算法驚艷了你? - 調查類問題
然後就是代碼健壯性的考慮與優秀代碼編寫方式的學習,還記得第一次接項目的時候,被導師罵的狗血零頭(哭
至於後面的發展方向,大體有兩種
第一種,工業控制方向,比如汽車控制代碼的編寫,工業控制系統的編寫等等,其實,這方面我也不是很了解,因為身邊沒有人轉這方面的(別理我,我是在一本正經的裝逼
第二種,就是傳統意義上的嵌入式方向
如同 @肖沛前輩所說

從事安卓底層開發,工作一年,個人看法 ,處女答。個人感腳51就是就是搞嵌入式第一門技術。把c語言,模數電,硬體畫板等第一次聯繫起來。在學校的時候我們的學習路線是:1 : 51單片機(大二上學期的時候,我感覺我還是接觸的挺晚的,嵌入式) 2:stm32+ucos ii (大二下學期到大三下學期) 3:Arm+linux (大四到畢業) 4.安卓驅動 ,JNI(工作,mtk平台)。然並卵,這句話適合51,但是也是非常非常非常重要的基礎。如果作為學生的話,參加比賽啥的51還是不夠用的。51作為最簡單的單片機,真真的簡單。相比於linux 安卓真的太簡單。

51作為入門之後,那麼接下來的就會面對Arm與Linux的考驗。System在具體Chip的移植,編寫對應的driver,等等這些都算是本職工作
恩,先寫這麼多,我去繼續日狗去了,這特么什麼日子啊(摔
對了,補充一下,學EE就是一個不斷日狗的過程,需要有及其強大的神經,恩,平時多日狗,用時少流淚,恩就這樣(逃


回應要求,發布成答案

============================================================

1.
原來寫好的代碼是「告訴」單片機控制各個埠來實現自己想要的功能的,只是原來寫代碼是「告訴」自己的PC,於是把單片機當成配置超級爛的PC看待;單片
機只是板上的一個晶元,和其他晶元一樣,只是各自集成度不同;板上的各種器件很多,那只是讓你學習和熟悉的,實際應用中的設計不是這回事。
2.
51單片機的編程,基本就是對著晶元手冊配置寄存器,所謂的教程都是翻譯了晶元手冊,好一點的告訴你哪兒有坑要注意下,所以要學會看晶元手冊;當然到了後
面更高端的單片機,也差不多是配置寄存器,只不過有的給了使用者一套底層函數庫,用不著直接在代碼里顯示地指明寄存器;更高級的直接跑操作系統。
3. 51單片機的集成資源比較少,寄存器管不了太多東西,這時就要靠埠模擬時序,要熟悉各種介面協議,個人覺得介面協議才是學習重點;另外,熟悉各個模塊的電路也是學習重點。

===============================================================

其實本人好久沒碰過單片機/控制器了,原理圖勉強可以看一看,模擬電路對我來說就是天書,畫PCB板難在布線,太需要經驗,這個技能我當然也沒有。


現在的我已經大三,回頭看一年前的答案很稚嫩,不過總結得還好,現在看到的朋友別誤入我當時的誤區:Altium Designer也好,Multisim也好,他們只是工具。工具只是手段不是目的,你了解單片機的原理才是學習的目的,回顧我答案的過程,發現花太多時間在學習工具上了,還有,建議大學生根據自己的職業規劃來確定學習的方向,多點上招聘網根據招聘崗位條件要求,學習相應的知識。
寫於2016年5月30
—————————華麗分割線——————————
現大二學生,從上年寒假開始學習單片機,準確來說是大一下學期開始接觸的。學習的時間斷斷續續,一直沒有堅持下去,大二才真正靜下心來學。剛開始覺得學這個很枯燥,是跟著郭天祥的視頻學習的,往往一個視頻1小時自己花了2小時,因為之前沒有基礎,現在學校老師教的是"高級語言"VB(發現大學有些課程挺扯蛋的),所以斷斷續續沒有接下去。不知道你們剛開始接觸的時候有沒有這種感覺,特別是對沒有C基礎的,不知道從哪學起,看視頻吧,看著看著就睡著了,自己搗鼓吧,也不知道從開發板哪裡開始。才泡了3個月,不能亂BB,但是這三個月的知識積累與我大學前1年相比簡直提升了一大層。這裡我享我學習過程,還需各位大牛多多指導,畢竟還有比我遲入門的,大牛可能沒時間幫他們,如果我的文章有幸能幫到其他人,也是我的榮幸嘛。在學51和PCB電路板時有疑問的朋友歡迎和我交流,同時也希望大牛能我們指導,哪裡說錯了過來噴噴。我現在比較有疑惑的是學Altium Designer,已經會畫板,但是生成PCB後,布線那些的有點迷茫。

1、一個沒有C基礎的的我,從師兄老師那打聽到學51從郭天祥的視頻開始,所以我就下載了全套來看。剛開始看真是頭都暈了,點亮一個LED燈還可以,到了第二課的延時函數就吃不消了,可以說我耐力差吧,沒有堅持,可以說我沒恆心吧,不是真正想學東西的人,當時的我沒有把它放心上,只是看了4課而已,其實對裡面的程序不太理解的,於是就停下來不學了。到了大二下學期,我發現要學點技術,所以重抄舊業,學期單片機,然後再重第1課開始看起,結果發現以前不明白的東西現在豁然開朗。我寫這經歷是想說,如果當時我堅持下去,不懂的地方看多幾遍,不懂再看再看,就不會浪費大半年的時間了。有些知識理論靠時間的積累,第一遍看不懂,第二遍看不懂,第三遍可能就懂一點了,剛開始上手一件事是會遇到類似的情況的。

2、當我學了1個月後,學校里有個比賽,團隊需要一個人搞硬體,於是我自己提出搞硬體,為什麼?因為在學單片機的過程中發現,自己只會跑程序,連原理圖都不怎麼會看,單片機的接線我都是看開發板提供的資料來接的,很狗血吧。。。於是我就開始接觸Altium Designer了,這是我這學期學的第二個軟體。是看視頻入門的,剛開始看的是郭天祥的視頻,結果發現看不下去啊,太長太累了,看完一集好痛苦啊,於是我搜搜,結果發現一個很好的教學視頻,用的也是比較新的版本,叫《邊學邊玩Altium Designer》 四人行工作室開的。我真的提感謝作者這種開源的精神的,對我們初學者幫助很大。跟著他的視頻學習1個月,會畫出51最小系統,基本布線,不過我覺得還是不夠(當然不夠啦,你才學了一個月。。。)

3、在學Altium Designer的過程中涉及到電路分析,也就是我們現在學的《電子電路基礎》,於是愛折騰的我開始搗鼓起Multisim 12.0,這是一款電路模擬模擬的軟體。跟著老師學挺慢的,但是教材又高深了一點,比如說分析放大電路,穩壓電源,教材上的東西大多列出公式,對於零基礎學習的朋友是挺苦逼的,而且老師也是趕鴨子式,講考試內容。這裡建議大家買一本書《電子設計零基礎》第二版,這本書是我在圖書館偶然發現的,但從此就迷戀上了他。剛開始他不會介紹一大堆公式,以一個例子開始教學,一步一步教你認識元器件(這裡對學PCB是有幫助的),然後從電路圖的一步分開始分析,接著分析怎麼系統,書本結合Multisim 模擬,教你一步一步使用裡面的控制項。

寫到這裡自己總結下:

對於1:學單片機最重要的是

  1.先認識單片機,了解單片機的主要組成和各個管腳的定義及功;推薦書《單片機原理及其介面技術》胡漢才(很熟悉吧。。呵呵這就是我們大學的單片機教材啊!!經典中的經典啊!基礎中的基礎啊!!人家幾十年的教材沒有變是有道理的,原理這種東西不會變到哪裡去的。不用專門去看,當作了解,對你理解編程是很有幫助的。)

  2.了解一些單片機彙編知識,方便後續調試;這本書《單片機原理及其介面技術》裡面就是講彙編的,一舉兩得。

  3.掌握單片機中斷機制;

  4.掌握單片機定時和計數器;(3和4是對單片機內部寄存器的控制,要熟練掌握。那些外部拓展功能大多都基於這些內部控制)

  5.掌握單片機的串口通信。

  以上是對想從事單片機學習的人必須掌握的基本內容。

對於2、3:2、3可以在一起講,這是硬體部分的。Altium Designer主要學原理圖庫設計,PCB庫設計,布線。沒入門的朋友看下視頻,不要求什麼都會畫,起碼要會用人家的庫,把人家的庫移植過來自己用,這樣可以快速上手這個軟體。到後來再慢慢完善自己不熟悉的地方,這在里一直頭疼我的就是封裝的問題,當時我連封裝是什麼都不懂,自己看視頻查了資料,才慢慢有點認識。請記住,學習一樣東西剛起步是最難熬的時候,也是最容易放棄的時候,這是我為什麼寫這文章的原因,因為我想和大家一起加油,為學精一樣東西而加油。從小家裡環境就沒辦法接觸這些的學問,也是大學才開始接觸電子編程這方面的東西,既然家長給了錢我們讀書,為什麼不好好利用,現在拿家裡的工資都不想著進步,等你畢業了,有哪家公司會給錢養你,供你求你學習。。擦扯遠了。。說到封裝,各位確實要自己花功夫百度一下,查下資料,形成自己的認識。

我現在比較有疑惑的是學Altium Designer,已經會畫板,但是生成PCB後,布線那些的有點迷茫。如有大牛看到請給些指點和推薦些學習的論壇,謝謝各位能看到此處。

最後推薦幾個網站給各位學習:單片機中文網 ( 單片機中文網-免費的單片機C語言教程和視頻教程! ) CSDN (CSDN.NET - 全球最大中文IT社區,為IT專業技術人員提供最全面的信息傳播和服務平台)

這裡引用一大神的帖,我當時看到把他複製下來了出處是這個論壇上一位大神(回首單片機學習,深度感悟,一席話少浪費你N年時光,經典)一條經典的入門學習路線是:C語言--51MCU(STC89C52)--增強型8位(STC15,STM8系列)--制板(AlltiumDesigner)--STM32F103--Cortex-A8(主要學習Linux或者Android).

寫於2015年6月


看到這個題目,我也想來扯兩句。從大一暑假呆在實驗室入門邊學51,邊學C。當時還天真的以為擁有了實驗室里的技術,我便擁有了整個夏天。
當時51我還用了一本郭天祥的一本書,開頭流水燈,然後數碼管,ad,da,串口啥的。學完後做了點小東西感覺自己好牛逼啊。後來又接觸其他430,STM32知道圖樣圖森木跑。樓主大學期間各種翹課在實驗室里,然後各種刷獎狀。然並卵。後來越來越覺得理論課重要了。同樣比賽,很多電路我們只能從網上抄襲,然而有大神自己就搭出來了。而且學習其他的也很快。
扯了很多沒用的,千萬不要以為會單片機很牛逼,其實很low,太皮毛了,兩層板,上位機真的是個人就能學。不要為了所謂的動手能力荒廢了理論課。一定好好學理論 一定好好學理論 一定好好學理論


本人本科是電子信息工程,大一放寒假的時候買了一塊開發板,自學了51。


那時候學校開始的課程主要是必修課程,像數學之類的,關於本專業的只有一門C語言。而且因為學校教學資源一般,並沒有真正掌握到什麼。在大一上學期的時候,學校組織了一次電子設計競賽,主要是面向高年級的。但是本人就是容易對這些好奇,就報名參加了。
選擇的題目是關於正弦波信號源的,其實和模電的關係更大,單片機就是起到控制和顯示的作用,而且這種題目網上一搜一大堆。可是對於當時的我來說,卻是相當的新鮮。首先單片機要能夠控制LCD1602顯示,然後還要有鍵盤輸入,還要能夠控制ADC,面對各種沒有聽說過技術指標以及網上下載的大堆的資料、代碼,完全沒有頭緒,但是從頭到位我都一隻很激動的對待著這次比賽。最終也的確沒有做出什麼來,只是使用Proteus進行了模擬,還像模像樣的寫了一篇論文,但是最讓我激動的是,最終我們拿了優秀獎(鼓勵獎),比起好多參加的高年級學長學姐們好多了!而且評測的老師,對我們組相當好,因為我們是大一,還主動給我們講了好多,鼓勵我們繼續做下去。現在想想,也真的很感謝那位老師。

可能扯的有點遠,但上述都是學習前的背景,正是有了這次比賽的激勵,我越發對單片機感興趣,於是放假前在網上收集了不少資料,(恕我多說了,當時向周圍的人包括高年級的,電子專業的人,對單片機居然了解的相當少,我很是奇怪,不過也正因為這樣,我變得更會使用網路了),也是那時候,聽說了郭天祥的教程,於是就找到他的視屏教程,特地跑到華龍電子商城買了一套開發板,足足三百塊(後來知道,這種東西是很便宜的,更何況我買的那個功能還相當少),就這樣湊齊了準備放假回家了~
(再插一段,回家的路上,我一直捧著開發板的盒子,都不敢把它放在箱子里,路上還時不時地拿出來看看,那時候真是~)

回去的第一天,我就跑到老家的市裡買了我的第一台筆記本電腦,回來之後就開始準備上手單片機,一切都是那麼激動,可是當我真的開始插上單片機的時候就面臨好多的問題,我是個愛折騰的人,自然不會卡在這:

1: 我的開發板上面的單片機是AT89S52的,而郭天祥教程是STC的,這導致他們的下載方式就不一樣了,前者是ISP,而後者是串口,用的軟體自然也不一樣,前者是AvrFighter,後者可以用好多種串口下載工具。當然這一切都是我糾結,折騰,鼓搗出來的。那時候我知道了晶元的型號,以及常用的兩種通訊方式,和常見下載的軟體;
2: 因為上述問題,我就必須使用AvrFighter下載,可是軟體卻總是提示沒法用,又是一番調查,才知道我的系統是64位,不支持或者說要改點什麼才能支持,硬著頭皮我又試了很多其他版本的軟體,又是修改註冊表什麼的,要知道這些在我沒有電腦之前聽都沒有聽過的。最終這個問題也解決了,從那時我知道操作系統的版本,註冊表,環境變數等等;
3: 心想這下總該可以了吧,可是當使用Keil寫出Led燈的程序的時候,下載之後卻沒有任何反應,這我真的不知道怎麼辦了。於是又是各種資料,還把課又聽了一遍,發現我的開發板和郭天祥的板子電路不一樣,管腳什麼的自然就不對應,我想起來開發板有光碟,裡面好像有不少資料,打開一看還真是相當多~~~,4G的資料,不過還是讓我找到了那個pdf的原理圖,真的是第一次,第一次看原理圖,心裡別提有多激動了。
在仔細扣完之後,大體上對我自己的板子了解了,終於我改寫了程序,讓我自己板子上的Led亮了!!!那是一個很小的成功,但對我來說,真的太難忘,太重要了,那個感覺永遠不會忘記~
後來我跟著課程,一遍努力看原理圖,一遍努力理解代碼並改寫,走過了流水燈,靜態、動態數碼管,掃描鍵盤,中斷鍵盤,LCD1602、12864......自從第一個燈亮了之後,之後的每天早上,我5點多鐘就爬起來,開燈開視頻,寫代碼,每天晚上都是被家人催上床的。閉上眼就是各種電路和代碼,以及成功運行的喜悅,沒有任何雜念,只是想去做。
當看完大概十課左右,基本上對51有了整體的了解,感覺彷彿體會到了單片機的本質,就是控制,使用普通IO口的控制,使用各種協議匯流排的控制,使用各種內置中斷計時器的控制,可能正是因為自己的板子有很多不同的地方,才會讓我對它理解深一點吧。

單片機學完,寒假也就結束了,大一下學期再次參加校電子競賽,拿了特等獎,這次依舊是信號源,沒有用高級的,還是只用了51。之後的暑假留在學校參加了省的電子設計競賽,接觸了MSP430,以及另外的一種控制核心CPLD/FPGA,有了前面的學習經驗,上手起來也比較快,再加上專業知識開始完善,最後拿了省的一等獎。後面還一直參加這樣的比賽,過程學習使用了STM32,瑞薩等等型號的主控,其實大同小異,掌握了學習的方法是最重要的。後來還做過一個STM32使用uCOS的MP3的設計,其中來了一次大綜合,SD卡和FTFS文件管理系統,TFT和uCGUI圖形界面,最底層的操作系統的植入,音頻解碼部分的設計等等,把學習的東西都用上了,直到現在,我對這些依舊保持著濃厚的興趣~

現在畢業快一年了,回想起當時學習51的時候,總是感慨萬千,興趣和努力是那麼重要,今天有機會就和大家分享了~希望對後輩有點幫助~

很晚了,純手打的,明天還要上班,所以就這樣啦~ (插圖一張,雖然和主題沒什麼關係~)


說說我的經驗。我個人認為最初期的51是很難學、很難用的,至少對我是這樣。我對著3本不同的書,啟動了三次,都沒有學會怎麼把一個LED閃爍起來。當然,當年資料少也是一個原因。幾年後,由於必須使用單片機,偶然的機會接觸了Microchip(微芯) 的 PIC系列單片機,沒想到一下子就鑽進去了,1個月熟練掌握,3個月後把用PIC單片機作為核心的研發的設備賣出去了。回頭想想,可能是我天生就是個精簡指令集的大腦,處理不了複雜的長跳轉吧。另外我用的是CCS-PICC編譯器,非常易用,從延時函數到1602液晶驅動,乃至IIC存儲晶元,都有現成的庫,2、3行代碼就可以用這個外設。再有一點是我學單片機時,各大公司樣片都給得比較大方,Microchip也是,要了一大堆樣片,回來輪流學著玩。再補充一句,網上老外的開源代碼很多,有很多是基於Microchip公司單片機的,我覺得看明白學會高手寫的代碼,比自己寫100倍數量的代碼還管用。

現在不同了,不管是51、PIC、AVR(已經被Microchip併購)、430,這些單片機開發起來,總體區別不是很大了,高級語言的基礎思路(我自己定義的):順序、循環、判斷搞明白了,不同的單片機只是IDE界面和IO、內設訪問方式不同,編程思路還是非常近似的。高級功能方面,掌握指針的靈活運用、簡單操作系統的使用、Bootloader一類的,基本8位單片機就精通得差不多了吧。(跑裸機的16位也包括在內。)

我後期一直沒有轉32位系統,因為我用8位機能解決大部分的應用問題,所以停滯不前了。現在老當益壯,再把32位機學起來,嵌入式linux也玩玩,做到老有所學、老有所養,哈哈哈。倚老賣老了,信心的氣球很容易一戳就破,不同觀點者輕拍為佳。


不邀自來…51成功的連通了C 彙編 數字電路 模擬電路
通俗來說…就是點個燈的全過程…
再往後,C再打包就成了數據結構和操作系統


51單片機是基礎學科,雖然它已停產好久。
首先把C 語言學好是必須的,51單片機編程對C 語言還是有一定的要求。
然後要把電路搞懂,學會看原理圖,會畫簡單的電路圖,51單片機對原理圖要求不是很高,只要用心很快就能理解。
個人覺得,你在學51時,不要著急著去敲代碼,先看它的資料文檔,建議看官方的資料,看晶元資料,看它的管腳定義的使用比較簡單,通俗的說就是給高低電平去控制即可。
了解了51的特性,知道它能幹嘛之後,先從最簡單的點亮LED 開始,哈哈……不過這裡要求你能後靈活快速的在進位數值之間轉換,給1或者0去控制LED 。這樣下來,你應該對它有一點了解了,這時可以做流水燈,數碼管之類的東西了。
幾個玩意下來,該學它的定時器和中斷了,個人覺得這個是玩51最重要的,沒有這兩個,基本玩不出什麼花樣。這裡就不詳細說它們的原理了,碼子好累……
基本走下來就完了吧,這時候玩一些小項目,得靠自己了。比如智能小車,藍牙小車,遠程控制系統等等……網上資料太多,慢慢學了……
回答的不好別噴,答主兩三年沒碰單片機了


沒有感覺的感覺。
模電沒學,不知道什麼是led
數電沒學,不知道什麼是寄存器
誤差分析沒學,不知道什麼是逐次逼近
高頻電路沒學,不知道什麼是射頻
微機原理沒學,不知道什麼是匯流排
至於電源,AD,架構什麼的,就更不要說了。
當掌握了以上課程,真的會發現自己曾經很傻很天真,抱著《 xxx十天學會xxx 》,專註那幾十行代碼,卻一直不得要領。


我是大二學生,大一剛來學校就加入實驗室。開始接觸單片機也是這個時候,我學的是51,教程是郭天祥的。學習單片機過程中有過各種各樣的問題,感觸最深的就是學的淺。網上教程雖多,但都是比較淺的。

我是用c語言編程的,相信這也是單片機編程的主流語言。學了兩年,編程也沒有什麼問題,但是也只局限於編出來,用模塊化編程。自己編出來的程序和網上的範例差別也不大,優化程序也在做。可是一涉及到演算法、系統之類的,就真的是望洋興嘆。

之前在知乎也關注了關於單片機的問題,看到他們說什麼演算法啊,系統啊,真的不知道那是什麼。還記得有個回答是讓題主在單片機上模擬單片機。看到這個回答真的感覺自己兩年都白學了…

對於單片機學習的心得有一些,但是因為我水平有限。學習過程中的心得或許比較低級,僅供各位參考。關於編程,只有一個建議,多看、比較著看。我接觸C語言也只有兩年,對於編程也不是很懂,編程過程中也沒發現自己有強到不行的天賦。開始對編程沒有感覺,就不斷的看別人寫的程序,把每行代碼都看懂。同一個功能,會有不同的人去編,會有不同編法。這時候對比這看會有很大收穫。
還有,編程最重要的一點是看手冊。C語言只是一種工具,一種控制方法。只要知道原理,方法會有很多的。

硬體沒什麼訣竅,只有多練,多想。

希望同樣學習單片機的同伴能夠互相交流~

手機打字真的好麻煩…先這樣吧…以後再補充。


沒有數電知識之前碰「毫無意義」
學得艱難還不知所以然
還會讓你誤以為自己很牛逼
不過這樣做還是會讓你提前學到很多零碎的、不成系統的知識
還是建議先學數電,先學微機再學單片機


野路子程序員為您講我國老一代單片機的故事。
八年前,哥們還是學渣中的學渣,那時最喜歡去垃圾堆撿廢舊電器,拆電路板,拆電機什麼的。
小夥伴從實驗室弄來了兩塊8031的單板機,我覺得那真的是有復古范的好玩具。第一印象這就是哪個國營廠造出來的物件,到手後清灰擦垢,接上個21世紀生產的5v電源,它亮了!
那貨看起來就是個自帶鍵盤和一排數碼管的簡易計算器,沒鍵盤介面滑鼠介面硬碟介面更別提網卡介面了。
咋玩呢?這板子自帶一套監控程序,功能就是初始化外圍晶元、再等著用戶按鍵盤編程,一切反饋信息都顯示在一行數碼管上,嗯,還是紅色的。
我還真跑到圖書館找到了這款單板機編程教材,自己複印了一份留存。,草草地研究一番之後,感覺找到了當年前輩在實驗室練習編程的神聖使命感。
機器早已不在,我到網上找到了這幅圖,大概能讓各位客官體會到那種原始電子美學。

好像九十年代的老前輩(甚至是八十年代?)都是這樣學單片機,或者說,那個年代就沒有今天這樣集成度這麼高的單片機,工控領域就別提了。
這裡有一篇文章值得一看:


第一台TP801單板微型計算機是怎樣誕生的

作者:劉川賢
  1978年,經過文化大革命後,我國高校教學、科研開始走上正軌的時候,對科技發展新動向很敏感的我校二系主任龔為珽老師,對國外七十年代以後出現並成為最熱門的新技術——微處理器十分關注。親自帶領二系幾位老師(徐家棟、吳定榮、顏超及從射流研究室調來的劉川賢)成立自動化研究室。目標就是對準微處理機及其在工業自動化中的應用。為了壯大這支隊伍,先後又調進陳平、靳彤老師及原二系優秀畢業生候伯文等同志以及自裝車間的技術人員及工人。但是在改革開放之初,我們既無資金,又無樣機,無從下手。1979年除部分同志參與校組織的激光印表機研製工作外(註:我校激光印表機獲北京市1980年科技成果一等獎),大家還是在查找和鑽研微處理機資料的前期工作。一次偶然的機會來了:1980年初,香港一家公司在北京的一次展覽會上,展出美國的一種教學用的Z80單板微型機,在給參觀者表演此機的功能時,出了故障。參展的香港商人不懂此種微型機的具體技術,通過當時我校科研處的李世偉同志,拿到我研究室讓老師們看一看。由於研究室老師事前鑽研過微處理機資料,聰明能幹的吳定榮老師很快找到該單板微型機的故障,並加以解決。第二天港商知道此微機修好的消息後,十分驚訝!覺得北工大確實有懂行的人才。於是把此單板微型機送給了我們研究室,並建議與我校合作進行微機的開發、研究、生產。這對我們來說是求之不得的,雙方很快達成協議。協議書規定由此家港商負責進口國外晶元、元器件,我們負責軟體和硬體線路的開發。有了這台美國的樣機,大家非常高興,馬上進行反覆試驗。徐家棟和顏超兩位老師把單板機英文的資料翻譯成中文;吳定榮等老師把其硬體吃透後,設計出新的單板機硬體。侯伯文老師用了幾個晚上讀懂並消化吸收了樣機的監控程序(該機的系統軟體)。侯老師又和吳老師緊密配合,重新編排了新單板機的監控程序。新型單板樣機由研究室劉淑清等技術工人精心焊接。新機內存是原樣機的四倍,功能也比樣機更齊全,並可直接用在工業自動化和教學實驗中。新樣機完成並試驗合格後,港商公司十分滿意。雙方共同為此新產品取名為TP801單板微型計算機。港商表示要立即批量進來晶元及必需的器件,由北工大生產。此時李世偉與我校原三系電子廠聯繫,讓該廠轉產(該廠以前生產穩壓電源),專門從事TP801單板機的生產。這樣又有了幾十位技術人員和工人的生產廠家。不久批量TP801單板機投放市場;同時由研究室龔為珽等老師編輯出版了有關單板機的教材;再由研究室老師主講的TP801單板機原理及其應用的學習班一期又一期的舉辦。學習班在北京、在全國辦了幾十期,參加者蜂擁而來,效果非常顯著。報名參加學習班的有從全國各地來的高校教師、科研部門和工廠的技術骨幹。由於在當時TP801單板機是我國第一台功能較好且實用性較強的單板機。全國各地廠礦企業、研究所及高校紛紛前來購買。各單位都是幾十、幾百台的購買,如有一次清華大學一下子就購買一百台,以致於有時產品供不應求。北京工業大學也由此而在全國名聲大振。全國許多專業人士異口同聲地稱讚北工大的TP801單板機是中國電子計算機發展的一個里程碑;北京工業大學電子廠是全國高校校辦產業的典範!等等。北工大二系自動化研究室後來擴大為微機應用研究所。在已有的成績基礎上,他們繼續努力,又完成了TP803 、TP805 、TP807 、TPSTD 等系列型號工業微機和幾十種介面板的研製。還在工程項目的應用上做出了很大成績。並且在培養工程碩士研究生人才方面有很多貢獻。經濟效益也是可觀的,僅82年一年銷售TP801單板機2030台,香港銷售730台,小印表機國內銷售1731台香港銷售673台,PS-1電源,國內銷售993台,香港銷售40台,電子廠產值達7079.2萬元,銷售額1031萬元,利潤513.6萬元,上繳學校271.6萬元,有利的支援了學校教學改革。學無止境,科學研究無止境,教職工們在為國家的騰飛繼續做著新的貢獻。
  通過TP801單板微型計算機這一著名產品的研製及生產的實例,我們可看到改革開放對我國科技進步、生產建設和經濟騰飛起了多麼巨大的促進作用!也可以看到我們北工大教職工有團結合作、刻苦鑽研、不怕困難、敢於創新的優良傳統!(作者:北京工業大學科技產業 教授)

當年前輩們都是這麼玩自己的:
先給自己大腦編程,把指令大概記一下,然後自己把程序結構構思一下,在紙上畫個草圖,腦子笨一點的就把指令也一條條寫好,自己用大腦編譯一遍沒問題了,就可以一點點把指令敲進單板機,然後等那排紅色的數碼管發出魅惑的閃光。
這幅圖也是從網上扒來的,應該是哪個前輩的作業,如有侵權,請告之刪除。

還有那個IO口,插座極端奇葩,哥們為了讓它點個LED燈,還得自己飛線。
原始人一般的學習持續了兩周,中間夾雜著各種鍵盤帽脫落和大腦編譯器崩潰,最後哥們放棄了,轉投實驗室里的高大上51單片機實驗箱。
後來哥們又去犯賤,去電子市場找做PCB的老闆買別人做剩下的板子,對著板子反推出原理圖滿市場轉悠湊零件,一邊被賣電阻的大媽調戲,一邊去調戲賣at89s51的姐姐。
然後,一段神奇的經歷開始了~


說說我自己的經歷。
1、學習51之前,先把C語言學好。還有數電模電,微機原理,基礎的東西一定得掌握。
2、學習單片機比較有效的方法是看C常式,特別是寫的比較好的,從中可以學到很多東西。在Keil官網上的常式就是很好的教材,儘早培養出良好的編程習慣。
3、51單片機只是一把梯子,基礎學好了就該往上走了。


只是一種工具或一門課,千萬不要有錯覺覺得自己實現了點東西就很nb


51,是單片機入門,因為裡面寄存器不多,操作簡單,可以慢慢了解到單片機的精髓,往後學習會比較簡單,個人走了彎路,如果你要往軟體做,不要太早接觸單片機,學好c語言,這是慘痛的教訓


大一學51兩天就學會了,覺得自己好厲害,後來覺得這他媽是什麼鬼。自己真是個渣,滾去學習吧,自己不懂得不是一點兩點


#include&
#define uint unsigned int
#define uchar unsigned char
uchar n=1, i=1, State=1,rate=10;
/* 聲明馬達輸出埠 */
sbit MotorL_1=P2^5; //電機左驅動口 IN1
sbit MotorL_2=P2^4; //電機左驅動口 IN2
sbit MotorR_1=P4^4; //電機右驅動口 IN1
sbit MotorR_2=P4^5; //電機右驅動口 IN2
sbit key=P4^1;
sbit key1=P3^7;

void forward(void);
/*
void backward(void);
void revolve(void);
void revolve2(void);
*/
int keyscan(void);

void TimerInit(void);
//void left(void);
//void right(void);
void main(void)
{
TimerInit();
P4SW=0x70;
while(1)
{


/*keyscan2();
if(State==1)
{
MotorL_1=1; MotorL_2=1;MotorR_1=1; MotorR_2=1;
}
else if(State==2)
{
forward();
}*/

keyscan();


}
}

void forward(void)
{
MotorL_1=1; MotorL_2=0;
MotorR_1=1; MotorR_2=0;
}
/*
void backward(void)
{
MotorL_1=0; MotorL_2=1;
MotorR_1=0; MotorR_2=1;
}

void revolve(void)
{
MotorL_1=1; MotorL_2=0;
MotorR_1=0; MotorR_2=1;
}

void revolve2(void)
{
MotorL_1=0; MotorL_2=1;
MotorR_1=1; MotorR_2=0;
}

void left(void)
{
MotorL_1=1; MotorL_2=1;
//MotorR_1=1; MotorR_2=0;
}

void right(void)
{
MotorL_1=1; MotorL_2=0;
MotorR_1=1; MotorR_2=1;
}*/

int keyscan(void)
{
if(key==0)
{
if(key==0)
{
n=n+100;
if(n&>=1000)
n=100;
}
while(key==0);
}
return n;
}


void TimerInit(void)
{
TMOD=0X01;
TH0=(65536-80)/256;
TL0=(65536-80)%256;
EA=1;
ET0=1;
TR0=1;
}

void TimerA_InterruptServiceRoutine(void) interrupt 1
{

TH0=(65536-80)/256;
TL0=(65536-80)%256;
i++;
if(i&>=n)
{
MotorL_1=1; MotorL_2=0;MotorR_1=1; MotorR_2=0;
}
else if(i& {
MotorL_1=0; MotorL_2=0;MotorR_1=0; MotorR_2=0;
}
else if(i==1001)
i=0;
}
理解這個程序的PWM波的實現過程,你就入門了,這個是自己寫的最簡單的程序了,當然最好還是學好英語,過了六級再說,方便閱讀DATEsheet


推薦閱讀:

一個廢舊的 Android 手機能拿來幹什麼有趣的事?

TAG:嵌入式系統 | 單片機 | IT教育 | 51單片機 | 微處理器 |