找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2178|回復(fù): 10
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)求助,求大佬幫忙修改一下代碼,注釋齊全,實(shí)在不知道哪里錯(cuò)了QAQ

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:480568 發(fā)表于 2019-8-2 20:06 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
100黑幣
我想用51單片機(jī)做一個(gè)蓋革計(jì)數(shù)器,蓋革管發(fā)出脈沖經(jīng)過(guò)芯片過(guò)濾成方波,用外部中斷器1進(jìn)行計(jì)數(shù),定時(shí)器0定20s通過(guò)公式計(jì)算一次輻射強(qiáng)度然后通過(guò)1602顯示,定時(shí)器1專門(mén)用于延時(shí)的定時(shí),不知道為什么老卡在歡迎語(yǔ)那里不動(dòng),請(qǐng)大佬指點(diǎn)QAQ這卡了我一個(gè)星期卡的好難受啊,以下是代碼:
/*********************************************************************
*名稱:蓋革計(jì)數(shù)器
*功能:測(cè)量電離輻射值
*版本:0.13
*********************************************************************/
#include <reg51.h>
#include "lcd.h"
#define _2s 200     //延時(shí)2s
float S;    //單精度數(shù)
uint t;     //定義全局變量用于延時(shí)計(jì)數(shù)
uint k;     //定義全局變量用于計(jì)算脈沖數(shù)
sbit rad  =  P3^2;     //電離計(jì)數(shù)
sbit beep =  P1^0;     //蜂鳴器引腳
uchar revo[]="   Revolution!  ";     //歡迎語(yǔ)部分
uchar dang[]="     Danger!    ";     //危險(xiǎn)輻射報(bào)警
uchar radi[]="    Radiation   ";     //輻射值標(biāo)題
uchar code unit[5]   =    {'u','S','v','/','h'};                             //輻射單位顯示數(shù)組
uchar code ASCII[11] =    {'0','1','2','3','4','5','6','7','8','9','.'};     //數(shù)字顯示數(shù)組
uchar disbuff[8]    ={0,0,0,0,0,0,0,0};
bit flag = 0;
/*********************************************************************
*名稱:定時(shí)器模塊
*功能:定時(shí)器延時(shí)及中斷
*輸入:無(wú)
*輸出:無(wú)
*********************************************************************/
void delayms(uint x)//定時(shí)器10毫秒級(jí)延時(shí)函數(shù)
{
t=x;
while(t);
}
void InitTimer0()//定時(shí)器0初始化函數(shù)(得到20s時(shí)間計(jì)時(shí))
{
TMOD=0x01;     //定時(shí)器0,工作方式1
//定時(shí)10ms
TH0 = 0xDC;     //高八位
TL0 = 0x00;     //低八位
ET0= 1;        //打開(kāi)定時(shí)器0中斷
EA = 1;        //打開(kāi)總中斷
TR0= 1;        //打開(kāi)定時(shí)器0
}
void InitTimer1()//定時(shí)器1初始化函數(shù)(延時(shí)定時(shí)器)
{
TMOD=0x10;     //定時(shí)器1,工作方式1
//定時(shí)10ms
TH1 = 0xDC;     //高八位
TL1 = 0x00;     //低八位
ET1= 1;        //打開(kāi)定時(shí)器1中斷
EA = 1;        //打開(kāi)總中斷
TR1= 1;        //打開(kāi)定時(shí)器1
}
void Timer0() interrupt 1  //定時(shí)器1服務(wù)函數(shù)
{
static uint i;
TH1=0XDC;
TL1=0X00;
i++;
if(i==2000)     //20s計(jì)算一次
{
  i=0;
}
}
void Timer1() interrupt 3  //定時(shí)器0服務(wù)函數(shù)
{
TH0 = 0xDC;
TL0 = 0x00;
t--;
}
/*********************************************************************
*名稱:顯示模塊
*功能:lcd1602液晶顯示
*輸入:無(wú)
*輸出:無(wú)
*********************************************************************/
void welcome()//歡迎語(yǔ)函數(shù)
{
InitLcd1602();            //屏幕初始化
LcdShowStr(0,0,revo);     //顯示歡迎語(yǔ)
delayms(_2s);
Lcd1602_Write_Cmd(0x01);  //清屏  
LcdShowStr(0,0,radi);     //顯示輻射標(biāo)題
DisplayOneChar(4,1,ASCII[10]);    //顯示小數(shù)點(diǎn)
DisplayOneChar(11,1,unit[0]);     //顯示輻射單位uSv/h
DisplayOneChar(12,1,unit[1]);
DisplayOneChar(13,1,unit[2]);
DisplayOneChar(14,1,unit[3]);
DisplayOneChar(15,1,unit[4]);
}
/*********************************************************************
*名稱:外部中斷模塊
*功能:外部中斷計(jì)數(shù)及危險(xiǎn)報(bào)警
*輸入:無(wú)
*輸出:無(wú)
*********************************************************************/
void Int1Init()
{
//設(shè)置INT1
IT1=1;//跳變沿出發(fā)方式(下降沿)
EX1=1;//打開(kāi)INT1的中斷允許。
EA=1;//打開(kāi)總中斷
}
void Int1() interrupt 2  //外部中斷1的中斷函數(shù)(測(cè)量蓋革管脈沖數(shù))
{
delayms(1000);  //延時(shí)消抖
if(rad==0)
  ++k;
if(k>65535)
  flag=1;
}
/*********************************************************************
*名稱:脈沖計(jì)數(shù)模塊
*功能:蓋革計(jì)數(shù)器脈沖計(jì)數(shù)
*輸入:無(wú)
*輸出:無(wú)
*********************************************************************/
void calculate()
{
  S=k/(1.67*235);
  k=0;
if(S>=9999||flag==1)
{
  Lcd1602_Write_Cmd(0x01);  //清屏
  LcdShowStr(0,0,dang);     //顯示危險(xiǎn)
  while(1)
  {
   beep=~beep;        //蜂鳴器常響,LED燈常亮
   delayms(1);        //頻率尖銳
  }
}
else
{
  long A;
  A=S*10000;
  disbuff[0]=A/10000000;        //千位   
  disbuff[1]=A%10000000/1000000;     //百位
  disbuff[2]=A%1000000/100000;     //十位
  disbuff[3]=A%100000/10000;     //個(gè)位
  disbuff[4]=A%10000/1000;     //十分位
  disbuff[5]=A%1000/100;     //百分位
  disbuff[6]=A%100/10;     //千分位
  disbuff[7]=A%10;     //萬(wàn)分位
  
  DisplayOneChar(0, 1, ASCII[disbuff[0]]);
  DisplayOneChar(1, 1, ASCII[disbuff[1]]);
  DisplayOneChar(2, 1, ASCII[disbuff[2]]);
  DisplayOneChar(3, 1, ASCII[disbuff[3]]);
  DisplayOneChar(5, 1, ASCII[disbuff[4]]);
  DisplayOneChar(6, 1, ASCII[disbuff[5]]);
  DisplayOneChar(7, 1, ASCII[disbuff[6]]);
  DisplayOneChar(8, 1, ASCII[disbuff[7]]);
}
}
/*********************************************************************
*名稱:main
*功能:蓋革計(jì)數(shù)器
*輸入:無(wú)
*輸出:無(wú)
*********************************************************************/
void main()
{
InitTimer0();  //設(shè)置定時(shí)器0
Int1Init();    //設(shè)置外部中斷1
InitTimer1();  //設(shè)置定時(shí)器1

welcome();     //歡迎語(yǔ)
calculate();   //計(jì)算輻射強(qiáng)度
}


最佳答案

查看完整內(nèi)容

我寫(xiě)的電壓表的顯示歡迎語(yǔ)的函數(shù),實(shí)際可以正常操作 unsigned char code mytable1[]="4 Chanel Voltmeter!"; unsigned char code mytable2[]="51hei.com"; ……… void lcdinit(void)//初始化LCD { unsigned char t; delay(300); comm(0x38); delay(100); comm(0x38); delay(100); comm(0x38); delay(100); comm(0x38); comm(0x38); comm(0x08); comm(0x01); comm(0x06); comm(0x0c); comm(0x80) ...
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:97554 發(fā)表于 2019-8-2 20:07 | 只看該作者
我寫(xiě)的電壓表的顯示歡迎語(yǔ)的函數(shù),實(shí)際可以正常操作



unsigned char code  mytable1[]="4 Chanel Voltmeter!";
unsigned char code  mytable2[]="51hei.com";

………

void lcdinit(void)//初始化LCD
{
unsigned char t;
delay(300);
comm(0x38);
delay(100);
comm(0x38);
delay(100);
comm(0x38);
delay(100);
comm(0x38);
comm(0x38);
comm(0x08);
comm(0x01);
comm(0x06);
comm(0x0c);
        comm(0x80);         
        for(t=0;t<18;t++)         
        {
                LcdDis(mytable1[t]);
                delay(10000);             //語(yǔ)句進(jìn)入的快慢
        }
                comm(0xc5);           //第二行,從第一格開(kāi)始顯示

        for(t=0;t<9;t++)      
        {
                LcdDis(mytable2[t]);
                delay(10000);            //語(yǔ)句進(jìn)入的快慢
        }
        delay(50000);
        delay(50000);
        delay(50000);       //這個(gè)三個(gè)延時(shí)決定歡迎語(yǔ)的顯示時(shí)間長(zhǎng)短
        comm(0x01);      //清屏指令  每次顯示下一屏內(nèi)容時(shí),必須清屏
        comm(0x80);  
}


………………

回復(fù)

使用道具 舉報(bào)

板凳
ID:97554 發(fā)表于 2019-8-3 11:20 | 只看該作者
InitLcd1602();   
沒(méi)發(fā)現(xiàn)這個(gè)函數(shù)

把歡迎語(yǔ)放在這個(gè)初始化函數(shù)里,加上延時(shí),然后清屏。

顯示函數(shù)直接顯示數(shù)據(jù)界面應(yīng)該就OK了
回復(fù)

使用道具 舉報(bào)

地板
ID:97554 發(fā)表于 2019-8-3 11:24 | 只看該作者
把 lcd.c貼上來(lái),void welcome不需要作為一個(gè)函數(shù)放在主程序里吧,直接把歡迎語(yǔ)句放在初始化程序里,延時(shí)后清屏,然后進(jìn)入主界面不就完事了嗎?
回復(fù)

使用道具 舉報(bào)

5#
ID:88481 發(fā)表于 2019-8-3 11:52 來(lái)自手機(jī) | 只看該作者
在執(zhí)行定義定時(shí)器1初始化時(shí)影響了定時(shí)器0。應(yīng)該在定時(shí)器1初始化函數(shù)中"TMOD=0x10"改為"TMOD |= 0x10"
回復(fù)

使用道具 舉報(bào)

6#
ID:480568 發(fā)表于 2019-8-3 14:56 | 只看該作者
楊雪飛 發(fā)表于 2019-8-3 11:34
我寫(xiě)的電壓表的顯示歡迎語(yǔ)的函數(shù),實(shí)際可以正常操作

好的好的,我試試
回復(fù)

使用道具 舉報(bào)

7#
ID:480568 發(fā)表于 2019-8-3 14:57 | 只看該作者
883 發(fā)表于 2019-8-3 11:52
在執(zhí)行定義定時(shí)器1初始化時(shí)影響了定時(shí)器0。應(yīng)該在定時(shí)器1初始化函數(shù)中"TMOD=0x10"改為"TMOD |= 0x10"

謝謝,我試一下
回復(fù)

使用道具 舉報(bào)

8#
ID:480568 發(fā)表于 2019-8-3 14:59 | 只看該作者
楊雪飛 發(fā)表于 2019-8-3 11:24
把 lcd.c貼上來(lái),void welcome不需要作為一個(gè)函數(shù)放在主程序里吧,直接把歡迎語(yǔ)句放在初始化程序里,延時(shí)后 ...

lcd.c用的是普中給的超聲波測(cè)距的,我覺(jué)得那個(gè)比較好用
#include"lcd.h"


void Read_Busy()           //忙檢測(cè)函數(shù),判斷bit7是0,允許執(zhí)行;1禁止
{
    unsigned char sta;      //
    LCD1602_DB = 0xff;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do
    {
        LCD1602_EN = 1;
        sta = LCD1602_DB;
        LCD1602_EN = 0;    //使能,用完就拉低,釋放總線
    }while(sta & 0x80);
}

void Lcd1602_Write_Cmd(unsigned char cmd)     //寫(xiě)命令
{
    Read_Busy();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_EN = 1;
    LCD1602_EN = 0;   
}

void Lcd1602_Write_Data(unsigned char dat)   //寫(xiě)數(shù)據(jù)
{
      Read_Busy();
      LCD1602_RS = 1;
      LCD1602_RW = 0;
      LCD1602_DB = dat;
      LCD1602_EN = 1;
      LCD1602_EN = 0;
}

void LcdSetCursor(unsigned char x,unsigned char y)  //坐標(biāo)顯示
{
    unsigned char addr;
    if(y == 0)
        addr = 0x00 + x;
    else
        addr = 0x40 + x;
   
    Lcd1602_Write_Cmd(addr|0x80);
}

//按指定位置顯示一個(gè)字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF; //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40; //當(dāng)要顯示第二行時(shí)地址碼+0x40;
        X |= 0x80; //算出指令碼
        Lcd1602_Write_Cmd(X); //發(fā)命令字
        Lcd1602_Write_Data(DData); //發(fā)數(shù)據(jù)
}


void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //顯示字符串
{
    LcdSetCursor(x,y);      //當(dāng)前字符的坐標(biāo)
    while(*str != '\0')
    {
        Lcd1602_Write_Data(*str++);
    }
}

void InitLcd1602()              //1602初始化
{
    Lcd1602_Write_Cmd(0x38);    //打開(kāi),5*8,8位數(shù)據(jù)
    Lcd1602_Write_Cmd(0x0c);
    Lcd1602_Write_Cmd(0x06);
    Lcd1602_Write_Cmd(0x01);    //清屏   
}
回復(fù)

使用道具 舉報(bào)

9#
ID:480568 發(fā)表于 2019-8-3 15:04 | 只看該作者
883 發(fā)表于 2019-8-3 11:52
在執(zhí)行定義定時(shí)器1初始化時(shí)影響了定時(shí)器0。應(yīng)該在定時(shí)器1初始化函數(shù)中"TMOD=0x10"改為"TMOD |= 0x10"

我后來(lái)直接刪除了定時(shí)器1的運(yùn)用,直接用普通的while來(lái)做延時(shí),但是還是卡在最開(kāi)始顯示的地方啊。。。
回復(fù)

使用道具 舉報(bào)

10#
ID:213173 發(fā)表于 2019-8-4 05:54 | 只看該作者
void main()
{
InitTimer0();  //設(shè)置定時(shí)器0
Int1Init();    //設(shè)置外部中斷1
InitTimer1();  //設(shè)置定時(shí)器1

welcome();     //歡迎語(yǔ)
calculate();   //計(jì)算輻射強(qiáng)度
}
樓主這樣寫(xiě)主程序是無(wú)法正常運(yùn)行的,MCU永遠(yuǎn)處于重復(fù)不斷的初始化狀態(tài)。
回復(fù)

使用道具 舉報(bào)

11#
ID:480568 發(fā)表于 2019-8-5 16:24 | 只看該作者
wulin 發(fā)表于 2019-8-4 05:54
void main()
{
InitTimer0();  //設(shè)置定時(shí)器0

呃呃。。。剛學(xué)的定時(shí)器和計(jì)數(shù)器,那大佬有什么好方法嗎?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表