51單片機是對所有兼容Intel 8031指令系統的單片機的統稱。該系列單片機的始祖是Intel的8004單片機,後來隨著Flash rom技術的發展,8004單片機取得了長足的進展,成為應用最廣泛的8位單片機之一,其代表型號是ATMEL公司的AT89系列,它廣泛應用於工業測控系統之中。很多公司都有51系列的兼容機型推出,今後很長的一段時間內將佔有大量市場。51單片機是基礎入門的一個單片機,還是應用最廣泛的一種。需要注意的是51系列的單片機一般不具備自編程能力。
B. c51單片機是如何寫入程序的
1
通過燒寫器寫入
2
如果單片機支持ISP
可通過ISP口寫入
3
如果單片機有JTAG口可通過JTAG口寫入
C. 求c51單片機電子鍾程序(c語言)
#include <reg51.h>
#define uchar unsigned char //定義unsigned int為uint
#define uint unsigned int //定義unsigned uchar為uchar
sbit LCD_RS = P2^0 ;
sbit LCD_RW = P2^1 ;
sbit LCD_EN = P2^2 ;
sbit D_SDA = P2^6; //定義74HC164數據線為P2.6埠
sbit D_SCL = P2^7; //定義74HC164數據線為P2.7埠
sbit CLK = P1^3; /*實時時鍾時鍾線引腳 */
sbit IO = P1^4; /*實時時鍾數據線引腳 */
sbit RST = P1^5; /*實時時鍾復位線引腳 */
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
uchar time[8] = {0x50,0x30,0x19,0x30,0x12,0x06,0x06};
//========= 延時函數 ============
//延時時間以1ms為單位
//s決定延時時間長短
void delay_ms(uint s)
{
uint x;
for(s;s>0;s--)
{
x = 200;
while(x--);
}
}
//========= 送出一個位元組給74HC164(實現串並轉換) ==========
void send_out(unsigned char out)//傳送一個位元組8位
{
uchar i;
D_SCL = 0;
for (i=8;i>=1;i--)
{
D_SDA = out&0x80; //送數據到數據口
D_SCL = 1; //時鍾線置1
D_SCL = 0; //送一時鍾
out<<=1; //左移
}
}
//========= 寫命令函數 ==========
void lcd_wcmd(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
send_out(cmd);
LCD_EN = 1;
LCD_EN = 0 ;
}
//========= 寫數據函數 ==========
void lcd_wdat(uchar dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
send_out(dat);
LCD_EN = 1;
LCD_EN = 0;
}
//========= LCD初始化函數 ==========
void lcd_init()
{
lcd_wcmd(0x38);
delay_ms(1);
lcd_wcmd(0x0c); //顯示開,關游標
delay_ms(1);
lcd_wcmd(0x06); //向右移動游標
delay_ms(1);
lcd_wcmd(0x01); //清除LCD顯示屏
delay_ms(1);
}
//========== 往DS1302寫入1Byte數據 (內部函數) =============
void w_byte(uchar dat)
{
uchar i;
for(i=8; i>0; i--)
{
IO = dat & 0x01;
CLK = 1;
CLK = 0;
dat = dat >> 1;
}
}
//======== 從DS1302讀取1Byte數據 (內部函數) ===================
uchar r_byte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >> 1;
ACC7 = IO;
CLK = 1;
CLK = 0;
}
return(ACC);
}
//========== 指定地址往DS1302寫入1Byte數據 (內部函數) =============
void write_byte(uchar addr, uchar dat)
{
RST = 0;
CLK = 0;
RST = 1;
w_byte(addr);
w_byte(dat);
CLK = 1;
RST = 0;
}
//========== 指定地址往DS1302讀1Byte數據 (內部函數) =============
uchar read_byte(uchar addr)
{
uchar ucData;
RST = 0;
CLK = 0;
RST = 1;
w_byte(addr);
ucData = r_byte();
CLK = 1;
RST = 0;
return(ucData);
}
//============ 設置ds1302日期和時間 =============
void write_ds1302(uchar *p)
{
uchar i;
uchar addr = 0x80;
write_byte(0x8e,0x00); // 控制命令,WP=0,寫操作
for(i =7; i>0; i--)
{
write_byte(addr,*p); // 秒 分 時 日 月 星期 年
p++;
addr +=2;
}
write_byte(0x8e,0x80); // 控制命令,WP=1,防寫
}
//============ 讀ds1302當前日期和時間 =============
void read_ds1302(uchar *p)
{
uchar i;
uchar addr = 0x81;
for (i=0; i<7; i++)
{
*p = read_byte(addr); //格式為: 秒 分 時 日 月 星期 年
addr += 2;
p++;
}
}
//============ 顯示函數 ===================
void lcd_disp()
{
uchar addr = 4;
lcd_wcmd(0x80 + addr);
lcd_wdat(((time[2]>>4)&0x0f)+0x30); //顯示小時
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat((time[2]&0x0f)+0x30);
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(':'); //顯示":"
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(((time[1]>>4)&0x0f)+0x30); //顯示分
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat((time[1]&0x0f)+0x30);
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(':'); //顯示":"
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(((time[0]>>4)&0x0f)+0x30); //顯示秒
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat((time[0]&0x0f)+0x30);
addr = 2;
lcd_wcmd(0xc0 + addr); //在第二行顯示年月日和星期
lcd_wdat('2'); //顯示2
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat('0'); //顯示0
addr++;
lcd_wdat(((time[6]>>4)&0x0f)+0x30); //年
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[6]&0x0f)+0x30);
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(' ');
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(((time[4]>>4)&0x0f)+0x30); //顯示月
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[4]&0x0f)+0x30);
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(' ');
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(((time[3]>>4)&0x0f)+0x30); //顯示日
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[3]&0x0f)+0x30);
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(' ');
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[5]&0x0f)+0x30); //顯示星期
}
//=========== 主函數 ===============
void main()
{
lcd_init(); // 初始化LCD
write_ds1302(time);
while(1)
{
read_ds1302(time); //讀DS1302數據
lcd_disp(); //LCD顯示
delay_ms(500); //延時0.5秒
}
}
這是一個電子時鍾,在LCD1602上顯示,時鍾晶元是DS1302
D. c51單片機c語言程序
用C51是多麼簡單的事情啊。你的每個燈的順序不說。不好寫。思路這樣的:sbit led1=P1^0;~~~把所有的燈都定一下。void delay(int ms){int x,y;for(x=ms;x>0;x--)for(y=110;y>0;y--);}一個Nms的延遲,要求是12M的晶振。void main(){while(1){led1=0;delay(1000);led1=1;裡面隨便寫了。}}
E. c51單片機程序下載
STC單片機下載程序需要注意:
1,冷啟動,目標板供電迴路里裝個開關,在STC
上位機
軟體中,點擊
下載程序按鈕後,斷開下,開關,然後再閉合,注意目標板電路中,如果存在較大的容性阻抗,斷開的時間要稍長寫,不然目標板沒徹底的
自放電
。
2,串口線是否好用,如果是10元左右很便宜的那種CH340
USB轉串口
線,則會經常發生單片機無響應,下載不成功,建議買根40元以上的USB轉串口線。
3,目標板上的
RS232
口接線正確否:串口線的RXD
TXD兩根線,連線是否正確?可以兩根線交換位置,再實驗下。
4,
波特率
設置正確,在下載STC15xx單片機時,以前曾經出現過,波特率設置不能太高的問題。
5,P1.6,P1.7引腳需要接地?
有的STC單片機不光需要冷啟動,還需要將這兩個引腳接地,才能下載程序。
以上是我在使用STC單片機時,發現的問題,
後來自己搞了個全自動的STC
下載器
,
用繼電器切換供電,CH340做USB轉串口。
用了個單片機自動檢測波特率。
通殺所有STC單片機,
這種產品好像淘寶上有不少在賣;
去搜索下
「STC自動下載器」。
F. c51單片機程序實例
#include<reg51.h>
#defineucharunsignedchar
uchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//0到9
ucharnum,cnt,disn;
ucharkeyval,disk;
ucharled[]={1,2,3,4};
voiddealdat(uchara)
{
led[0]=0;
led[1]=0;
led[2]=0;
led[3]=0;
led[a]=disk;
}
voiddelay(unsignedinta)
{
unsignedinti,j;
for(i=0;i<a;i++)
for(j=0;j<1000;j++);
}
voidt0isr()interrupt1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
switch(num)
{
case0:P2=0x01;break;
case1:P2=0x02;break;
case2:P2=0x04;break;
case3:P2=0x08;break;
default:break;
}
P0=~tab[led[num]];
num++;
num&=0x03;
cnt++;
if(cnt>100)
{
cnt=0;
disn++;
disn%=4;
dealdat(disn);
}
}
ucharkbscan(void)
{
unsignedcharsccode,recode;
P3=0x0f;//發0掃描,列線輸入
if((P3&0x0f)!=0x0f)//有鍵按下
{
// delay(20);//延時去抖動
if((P3&0x0f)!=0x0f)
{
sccode=0xef;//逐行掃描初值
while((sccode&0x01)!=0)
{
P3=sccode;
if((P3&0x0f)!=0x0f)
{
recode=(P3&0x0f)|0xf0;
return((~sccode)+(~recode));
}
else
sccode=(sccode<<1)|0x01;
}
}
}
return0;//無鍵按下,返回0
}
voidgetkey(void)
{
unsignedcharkey;
key=kbscan();
if(key==0){keyval=0xff;return;}
switch(key)
{
case0x11:keyval=7;break;
case0x12:keyval=4;break;
case0x14:keyval=1;break;
case0x18:keyval=10;break;
case0x21:keyval=8;break;
case0x22:keyval=5;break;
case0x24:keyval=2;break;
case0x28:keyval=0;break;
case0x41:keyval=9;break;
case0x42:keyval=6;break;
case0x44:keyval=3;break;
case0x48:keyval=11;break;
case0x81:keyval=12;break;
case0x82:keyval=13;break;
case0x84:keyval=14;break;
case0x88:keyval=15;break;
default:keyval=0xff;break;
}
}
main()
{
TMOD=0x11;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
getkey();
if(keyval!=0xff)disk=keyval;
delay(10);
}
}
G. 誰能幫幫忙 一簡單c51單片機程序
;這個程序當然是樓主要求的c51單片機程序。
;下面增加一些調試時使用的數據。
ORG 0000H
MOV 20H, #12H ;假設被加數NA是563412
MOV 21H, #34H
MOV 22H, #56H
MOV 30H, #77H ;假設加數NB是998877
MOV 31H, #88H
MOV 32H, #99H
LCALL ADD3B ;調用3位元組加法子程序
SJMP $ ;暫停,此時可以觀察和的數值:1562289
;-----------------------------------------------
;數字的位元組數不多,地址且有三個,故不用循環結構。
;程序如下:
ADD3B:
MOV A, 20H
ADD A, 30H
DA A
MOV 3FH, A
MOV A, 21H
ADDC A, 31H
DA A
MOV 40H, A
MOV A, 22H
ADDC A, 32H
DA A
MOV 41H, A
MOV A, #0
ADDC A, #0
MOV 42H, A
RET
H. c51單片機最小程序怎麼編程
編程,好說,十幾天就能學會。
你得先確定電路。
當人體接觸到紅外線感應器時,單片機的那個引腳,收到什麼電平?
帶動馬達轉動,是用單片機的那個引腳?用什麼電平驅動電機?
I. 編寫一個完整的單片機C51程序
#include<reg51.h>
sbit led=P1^0; //單片機管腳位聲明
void main()
{
TMOD=0x01; //定時器TO工作在方式1
TH0=(65536-5000)/256; //裝初值,12M晶振 1為1us; 5000為5000us=5ms;
TL0=(65536-5000)%256;
EA =1; //開總中斷
ET0=1; //開定時器TO中斷
TR0=1; //啟動定時器
P1=0; //初始化P1口
while(1) ; //程序在這里等待中斷發生
}
void T0_time() interrupt 1
{
unsigned char num;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
num++;
if(num==100) //0.5S (1s閃爍1次==0.5S亮0.5S滅)
{
num=0;
led=~led; //led狀態取反
}
}
J. C51單片機程序
TH0=0xf6;
TL0=0xff;
上兩行是定時器/計數器T0的初值,因為T0是16位的,所以用TH0表示高八位,TL0表示低八位
TH1=0xfd;
TL1=0xfd;
T1初值
TMOD=0x21;
定時器/計數器模式控制寄存器如圖
GATE=1時,由外部中斷引腳INT0、INT1來啟動定時器T0、T1
GATE=0時,僅由TR0,TR1置位分別啟動定時器T0、T1。
C/T=0時為定時功能,C/T=1時為計數功能
M0、M1——方式選擇功能
M1M0工作方式計數器模式TMOD(設置定時器模式)
00方式013位計數器TMOD=0x00
01方式116位計數器TMOD=0x01
10方式2自動重裝8位計數器TMOD=0x02
11方式3T0分為2個8位獨立計數器,T1為無中斷重裝8位計數器TMOD=0x03
PCON=0x00;
PCON主要是為CHMOS型單片機的電源控制而設置的專用寄存器
WDCON=0x00;清狗
SCON=0x50;
SCON1=0x40;
串口控制寄存器