標題: 我學51單片機 [打印本頁]
作者: 獵人平凡 時間: 2012-7-27 16:52
標題: 我學51單片機
學習單片機有段時間,為了與新人分享,同時也是對自己學習的一個總結,特發此貼,期待大蝦們的指點。
作者: 獵人平凡 時間: 2012-7-27 17:03
程序如下:
/*****************************************
函數名稱:void SMG(uchar n,uchar dat)
函數功能:給第n個數碼管(共陽)寫入數字dat
輸入參數:要顯示數字的數碼管n及數字dat
輸出參數:無
*****************************************/
#include "main.h"
#define SMG_DSP P2
#define SMG_CS P3
sbit SMG_CS1=P3^0;
sbit SMG_CS2=P3^1;
sbit SMG_CS3=P3^2;
sbit SMG_CS4=P3^3;
sbit SMG_CS5=P3^4;
sbit SMG_CS6=P3^5;
sbit SMG_CS7=P3^6;
sbit SMG_CS8=P3^7;
void smg(uchar n,uchar dat)
{
uchar i;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99, //0 1 2 3 4
0x92,0x82,0xf8,0x80,0x90, //5 6 7 8 9
0xa0,0x83,0xa7,0xa1,0x84, //a b C d E
0x8e,0xbf}; //F - // 共陽0 -
for(i=0;i<20;i++)
{
SMG_CS=0x00;
SMG_DSP=table[dat];
switch(n)
{
case 1: SMG_CS1=1; delay1ms(1); SMG_CS1=0; break;
case 2: SMG_CS2=1; delay1ms(1); SMG_CS2=0; break;
case 3: SMG_CS3=1; delay1ms(1); SMG_CS3=0; break;
case 4: SMG_CS4=1; delay1ms(1); SMG_CS4=0; break;
case 5: SMG_CS5=1; delay1ms(1); SMG_CS5=0; break;
case 6: SMG_CS6=1; delay1ms(1); SMG_CS6=0; break;
case 7: SMG_CS7=1; delay1ms(1); SMG_CS7=0; break;
case 8: SMG_CS8=1; delay1ms(1); SMG_CS8=0; break;
}
}
}
[此貼子已經被作者于2012-7-27 17:05:40編輯過]
作者: 獵人平凡 時間: 2012-7-27 17:05
程序如下:
/********************************
函數名稱:uchar key(void)
函數功能:4*4鍵盤掃描函數
輸入參數:無
輸出參數:鍵盤輸入的數據
********************************/
#include "main.h"
#define KEYP P1
uchar code keycode[4][4]={{16,0,16,16},{1,2,3,16},{4,5,6,16},{7,8,9,16}};
uchar key(void)
{
uchar col,row,scan,keyin,kcode;
uchar code keytable[4]={0xef,0xdf,0xbf,0x7f};
//高四位:掃描輸出(列);低四位:鍵盤輸入(行)
for(col=0;col<4;col++)
{
KEYP=keytable[col]; //逐列輸出掃描信號,逐行輸入
keyin=(~KEYP)&0x0f; //高四位:屏蔽;低四位:取反
if(keyin==0) //無按鍵按下
continue;
else //有按鍵按下
{
delay1ms(20); //延時去抖
if(keyin==0)
continue; //鍵盤抖動
else //不是抖動
{
for(row=0;row<4;row++)
if(keyin==0x01<<row) //只有row列按下
{
kcode=keycode[3-row][col];
break;
}
else //多列按下
continue;
while((~KEYP)&0x0f!=0); //等待按鍵釋放
}
}
}
return kcode;
}
作者: 獵人平凡 時間: 2012-7-28 12:15
/*************************************************************************************
LCD1602驅動函數
*************************************************************************************/
/*******************************寫命令說明******************************************/
/*0x01----0x03: 光標移至左上角,AC歸零(1.64ms)*/
//0x01 DDRAM填入空白
//0x02--0x03 DDRAM內容不變
/*0x04----0x07:字符、光標與AC控制(40us)*/
//0x04 D1D0=00:字符全部不動,AC-1,光標左移1格
//0x05 D1D0=01:字符全部右移1格,AC-1,光標不動
//0x06 D1D0=10:字符全部不動,AC+1,光標右移1格
//0x07 D1D0=11:字符全部左移1格,AC+1,光標不動
/*0x08----0x0f:字符與光標的開關控制(40us)*/
//0x08--0x0b D2=0,字符不顯示
//0x0c D2=1,字符顯示;D1D0=00,光標關
//0x0d D2=1,字符顯示;D1D0=01,光標閃爍
//0x0e D2=1,字符顯示;D1D0=10,光標顯示“_”
//0x0f D2=1,字符顯示;D1D0=11,光標顯示“_”與閃爍
/*0x10----0x1f:字符光標的移動控制(40us)*/
//0x10--0x13 光標左移
//0x14--0x17 光標右移
//0x18--0x1b 字符左移
//0x1c--0x1f 字符右移
/*0x20----0x3f:數據與顯示模式控制(40us)*/
//0x20--0x23 D4=0,數據總線為4位,D3=0,顯示1行,D2=0,點陣為5*7
//0x24--0x27 D4=0,數據總線為4位,D3=0,顯示1行,D2=1,點陣為5*10
//0x28--0x2b D4=0,數據總線為4位,D3=1,顯示2行,D2=0,點陣為5*7
//0x2c--0x2f D4=0,數據總線為4位,D3=1,顯示2行,D2=1,點陣為5*10
//0x30--0x33 D4=1,數據總線為8位,D3=0,顯示1行,D2=0,點陣為5*7
//0x34--0x37 D4=1,數據總線為8位,D3=0,顯示1行,D2=1,點陣為5*10
//0x38--0x3b D4=1,數據總線為8位,D3=1,顯示2行,D2=0,點陣為5*7
//0x3c--0x3f D4=1,數據總線為8位,D3=1,顯示2行,D2=1,點陣為5*10
/*0x40----0x7f:設定CGRAM地址(40us)*/
/*0x80----0x8f:設定DDRAM地址(40us)*/
/*******************************寫命令說明******************************************/
/*--------------------------------------------------------------*/
//所需頭文件
#include
#include
/*--------------------------------------------------------------*/
//LCD1602與單片機接口定義
#define LCD_IO P0 //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
sbit LCD_RS = P3^2; //LCD數據/命令選擇端(H/L)
sbit LCD_RW = P3^3; //LCD 讀/寫 選擇端(H/L)
sbit LCD_EN = P3^4; //LCD使能控制端
sbit LCD_BZ = P0^7; //LCD忙標志位
/*--------------------------------------------------------------*/
//檢測LCD忙狀態
void LCD_busy(void)
{
LCD_IO = 0xff; //P0口就需要設置
do
{
LCD_EN = 0;
LCD_RS = 0; //指令
LCD_RW = 1; //讀出
LCD_EN = 1; //高電平讀出
_nop_(); //延遲時間1us
}while(LCD_BZ); //LCD_BZ=1表示忙,LCD_BZ=0表示空閑
LCD_EN = 0;
}
/*--------------------------------------------------------------*/
//寫入指令
void LCD_cmd(unsigned char cmd)
{
LCD_busy(); //檢測忙
LCD_RS = 0; //指令
LCD_RW = 0; //寫入
LCD_EN = 1;
LCD_IO = cmd; //傳指令
LCD_EN = 0; //下降沿有效
}
/*--------------------------------------------------------------*/
//寫入數據
void LCD_dat(unsigned char dat)
{
LCD_busy(); //檢測忙
LCD_RS = 1; //數據
LCD_RW = 0; //寫入
LCD_EN = 1;
LCD_IO = dat; //傳數據
LCD_EN = 0; //下降沿有效
}
/*--------------------------------------------------------------*/
//定位輸出字符串
void LCD_prints(unsigned char x, unsigned char y, unsigned char *s)
{
if(x) LCD_cmd(y|0xc0); //x=1第二行顯示,x=0第一行顯示 0<=y<16
else LCD_cmd(y|0x80); //數據指針=80+地址碼(00H~27H,40H~67H)
while(*s)
{
LCD_dat(*s);
s++;
}
}
/*--------------------------------------------------------------*/
//LCD初始化
void LCD_init(void)
{
LCD_cmd(0x38);
LCD_cmd(0x0c);
LCD_cmd(0x06);
LCD_cmd(0x01);
}
/*--------------------------------------------------------------*/
歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |