全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:8120
推到 Plurk!
推到 Facebook!
[<<] [1] [2] [>>]

LCD如何顯示亂數

答題得分者是:scott123
qwerty1789
一般會員


發表:1
回覆:21
積分:4
註冊:2012-06-03

發送簡訊給我
#32 引用回覆 回覆 發表時間:2012-06-13 16:42:50 IP:111.255.xxx.xxx 訂閱
恩   我很感謝你們的幫忙^^   家裡沒有燒錄器 要到學校才能用  請多多見諒><

我知道A%B是取餘數 B改成50 就是取0~49 之前忽略了50這個數沒有
我是不清楚asc2hex(temp); 是可以把任意數轉成ASCII 還是只能轉個位數
void SerialInt_Init(void) 我是看不懂怎麼用 看過書了還是不懂 如果改B的值是否會影響

我把程式改成這樣
不過顯示好像怪怪的 是不是我改錯了 好像有刪掉一些副程式
按一次按鍵後會連續跳4個數字 爾且3.6.9很常出現 不知道是不是巧合


#include "REG51.H"
#include
#define first_row 0x80 //上面第一行
#define second_row 0xC0 //下面第一行
#define clear_display 0x01 //下面第一行
#define LCD_Data P0
#define RS P2_0
#define RW P2_1
#define Enable P2_2
sbit P2_0=0xa0;
sbit P2_1=0xa1;
sbit P2_2=0xa2;

unsigned char T0_count10ms=0;
unsigned char Int_10mstimebase;
unsigned int temp=0;
char one=0;
char zero=0;
int KeyData=0xff;
int KeyTemp=0xff;
void SerialInt_Init(void);
void SystemInit(void);
void delay1ms(unsigned int msec);
void delay10ms(unsigned int msec);
void print_data(unsigned char value);
void print_command(unsigned char value);
void KeyScan(void);
void WriteString(char *pMsg) ;
void lcm_init(void);
void asc2hex(unsigned char value);
void main(void)
{
char *MSG0="WELCOME";
lcm_init();
SerialInt_Init();
_nop_();
print_command(clear_display); //清除螢幕
print_command(0x80);
WriteString(MSG0);
while(1)
{
KeyScan();
if(KeyData==0)
{
print_command(0x01); //清除螢幕
print_command(0x80); //
temp=TL0 TH0;
temp=temp; //取除以10之後的餘數 0~9
asc2hex(temp); //經過轉換之後顯示在LCD上

delay1ms(60000);
delay1ms(60000);
}
}
}
///////////////////////////////////////////////////////////
void delay1ms(unsigned int msec)
{
unsigned char i;

while(msec--);
{
_nop_();
_nop_();
for(i=0;i<228;i );
}
}///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
void SerialInt_Init(void)
{
TMOD=0x20;
SCON=0x50; //mode3:鮑率可由timer1決定
//PCON&= 0x7F; //smod=0
REN=1;
TH1=0xFA;
TR1=1;
ES=1;

TMOD&=0xF0; //timer0 13bit mode0
TL0=(8192-462)2;
TH0=(8192-462)/32;
TR0=1;
ET0=1;

EA=1;
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////


void print_data(unsigned char value)
{
//if(b_checkBF==1)
//{
// check_BF();
//}
RS=1;
RW=0;
LCD_Data=value;
Enable=1;
delay1ms(5);
Enable=0;
delay1ms(5);
}
///////////////////////////////////////////////////////////
void print_command(unsigned char value)
{
//if(b_checkBF==1)
//{
// check_BF();
//}
RS=0;
RW=0;
LCD_Data=value;
Enable=1;
delay1ms(5);
Enable=0;
delay1ms(5);
}
///////////////////////////////////////////////////////////
//void check_BF(void)
//{
// LCD_EN=0;
// do{
// LCD_BF=1;
// LCD_RS=0;
// LCD_RW=1;
// LCD_EN=1;
// }while(LCD_BF==1);
//}
///////////////////////////////////////////////////////////
void lcm_init(void)
{
delay1ms(90);

print_command(0x38); //8位元 雙列 5x10點矩陣
print_command(0x38); //8位元 雙列 5x10點矩陣
print_command(0x0C); //字幕顯示 游標不顯示 不閃爍
print_command(0x01); //清除螢幕
print_command(0x02); //游標歸零
print_command(0x06); //游標右移 字幕不動
}
///////////////////////////////////////////////////////////
void asc2hex(unsigned char value)
{
unsigned char temp;

temp=value;
temp >>= 4;
temp = 0x30;
if(temp>0x39)
temp =0x07;
print_data(temp);

temp=value;
temp&=0x0F;
temp = 0x30;
if(temp>0x39)
temp =0x07;
print_data(temp);
}
void WriteString(char *pMsg)
{
while( *pMsg )
print_data( *pMsg );
}
void KeyScan(void)
{
char col,row;
char ScanLine=0x08;
int key=0;
int KeyStatus;
for(col=0;col<5;col )
{
P1=~ScanLine;
KeyStatus=~P1;
KeyStatus&=0xf0;
for(row=0;row<4;row )
{
if(KeyStatus==0x80)
{
one=0;
if(KeyTemp!=key)
{
KeyTemp=key;
zero=1;
}
else
{
if(zero!=5)
{
zero =1;
if(zero==5)
KeyData=KeyTemp;
}
}
}
key =1;
KeyStatus<<=1;
} /* row */
ScanLine>>=1;
} /* col */
one =1;
if(one==5)
{
zero=0;
KeyTemp=0xff;
KeyData=0xff;
}
} /* KeyScan */
scott123
中階會員


發表:19
回覆:66
積分:52
註冊:2011-08-11

發送簡訊給我
#33 引用回覆 回覆 發表時間:2012-06-13 17:30:52 IP:203.73.xxx.xxx 訂閱
如果範圍很小的話,你會發現某個數字好像常出現(心理作用)
如果把範圍加大,1~50再試看看,應該就不會很明顯

void SerialInt_Init(void)是我設定中斷的函數,我開了哪個中斷,做了什麼設定,我習慣寫在裡面
裡面我開了rs232的中斷和timer的中斷,我也懶得改,直接用沒差

asc2hex(temp); 抱歉,我仔細看了一下,我傳給你的範例程式用這一個沒錯,不過你的情形跟我的不一樣
你應該要自已寫一個轉換函數dec2asc(temp)

是按一次按鈕就跳了"4次"亂數嗎,
從keyscan下手,寫成key有被按下動作,或是寫成key有被放開來動作
以上兩種方法可以確保動作只被執行一次

8051燒錄器diy 網路上有很多教學,我自已做過一個,成本不用100元,很好做

===================引 用 qwerty1789 文 章===================
因為家裡沒燒錄器 不能馬上操作 不好意思
編輯記錄
scott123 重新編輯於 2012-06-13 04:09:07, 註解 無‧
qwerty1789
一般會員


發表:1
回覆:21
積分:4
註冊:2012-06-03

發送簡訊給我
#34 引用回覆 回覆 發表時間:2012-06-13 18:28:04 IP:111.255.xxx.xxx 訂閱
按一次鍵盤後 例如 從00變03~06~09
我在試看看是不是鍵盤沒弄好
謝謝解說^^
scott123
中階會員


發表:19
回覆:66
積分:52
註冊:2011-08-11

發送簡訊給我
#35 引用回覆 回覆 發表時間:2012-06-14 00:00:10 IP:118.170.xxx.xxx 訂閱
我看了你改寫的程式
如果是按了一下按鈕後放開
結果亂數跳了四次
那應該是keyscan沒有寫好
你的keydata沒有用好

while(1)
{
KeyScan();
if(KeyData==0)
{
print_command(0x01); //清除螢幕
print_command(0x80); //
temp=TL0 TH0;
temp=temp; //取除以10之後的餘數 0~9
asc2hex(temp); //經過轉換之後顯示在LCD上

delay1ms(60000);
delay1ms(60000);
}
}

===================引 用 qwerty1789 文 章===================
按一次鍵盤後 例如 從00變03~06~09
我在試看看是不是鍵盤沒弄好
謝謝解說^^
qwerty1789
一般會員


發表:1
回覆:21
積分:4
註冊:2012-06-03

發送簡訊給我
#36 引用回覆 回覆 發表時間:2012-06-15 19:29:38 IP:111.255.xxx.xxx 訂閱
請問這個可以做到 取範圍 和不重複功能嗎
例如:A%B C
可以把B和C改為變數嗎
scott123
中階會員


發表:19
回覆:66
積分:52
註冊:2011-08-11

發送簡訊給我
#37 引用回覆 回覆 發表時間:2012-06-17 23:01:53 IP:118.170.xxx.xxx 訂閱
取範圍當然可以
只是你要先寫一個lcd介面,讓使用者輸入範圍

我不知道你的不重覆是怎樣的功能
如果是類似樸克牌的不重覆
譬如1~52
那你要先把一大把的亂數先算好
等到要用的時後,再一個一個拿出來用


===================引 用 qwerty1789 文 章===================
請問這個可以做到 取範圍 和不重複功能嗎
例如:A%B C
可以把B和C改為變數嗎
編輯記錄
scott123 重新編輯於 2012-06-17 09:04:39, 註解 無‧
qwerty1789
一般會員


發表:1
回覆:21
積分:4
註冊:2012-06-03

發送簡訊給我
#38 引用回覆 回覆 發表時間:2012-06-18 17:23:29 IP:111.255.xxx.xxx 訂閱
恩  你說的先算好是類似洗牌程式??  最近上網有看到
我複製一段下來 改成1~50 他說主程式太大
那該怎麼辦

scott123
中階會員


發表:19
回覆:66
積分:52
註冊:2011-08-11

發送簡訊給我
#39 引用回覆 回覆 發表時間:2012-06-19 09:24:30 IP:203.73.xxx.xxx 訂閱

對,假設樸克牌,你把每一個張牌當成一個數字,1~52
經過洗牌運算之後,變成亂數,這樣就不會重覆,等到數字用完,就再洗牌一次

洗牌技巧(一):先把數字按序排好,然後亂數挑兩個數字,使得這兩個數字的位置的值交換
這樣重覆100次、1000次,即可達到洗牌效果

程式空間不夠,那就刪除一些不必要用的程式,不過這對初學者比較困難
第二個方法就是用89s52,這一個程式空間比51大一倍

===================引 用 qwerty1789 文 章===================
恩 你說的先算好是類似洗牌程式?? 最近上網有看到
我複製一段下來 改成1~50 他說主程式太大
那該怎麼辦

qwerty1789
一般會員


發表:1
回覆:21
積分:4
註冊:2012-06-03

發送簡訊給我
#40 引用回覆 回覆 發表時間:2012-06-19 18:05:53 IP:111.255.xxx.xxx 訂閱
可是我是HEX檔時 他說  4564.C(70): error C241: 'main': auto segment too large
srand((unsigned) time(NULL)) time需要time.h 但8051沒內建時鐘
如果用計數器代替 用你之前的程式 因為網路上找不到類似的 不知道怎麼做
如:
srand(temp) 這樣可以嗎??

int i,j,a[50];
for(i=0;i<50;i ){
a[i] = rand()P 1;
for(j=i;j>=0;j--){
if(a[i]==a[j]){
a[i] = rand()P 1;
網路上找到的 不過它顯示上面那個錯誤

編輯記錄
qwerty1789 重新編輯於 2012-06-19 04:08:14, 註解 無‧
qwerty1789 重新編輯於 2012-06-19 08:46:37, 註解 無‧
scott123
中階會員


發表:19
回覆:66
積分:52
註冊:2011-08-11

發送簡訊給我
#41 引用回覆 回覆 發表時間:2012-06-20 14:58:51 IP:118.170.xxx.xxx 訂閱
抱歉
我沒用過8051的time.h
亂數產生的方法我都是我之前講的方法
你可能要查一下那一個錯誤資訊是什麼意思

這一次我幫你查好了
http://hi.baidu.com/lbicecoffe/blog/item/b9c3d1d0412e658ba1ec9c7c.html




[<<] [1] [2] [>>]
系統時間:2017-12-13 11:18:09
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!