找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

求大神幫我改改這個程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:78901 發(fā)表于 2024-11-6 23:02 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
//------------------------------------------------------------------------------------
// Main.c
//------------------------------------------------------------------------------------
// Copyright (C) 2013 Shenyang JYXD.
// WEN BO RUI
// Tool chain: KEIL Full c
//
//#pragma CD OE DB SB // Compilation directives
#include <STC8G.H>
#include <intrins.h>
//#include
//#include
#define uchar unsigned char
#define uint unsigned int
uint Period; //Period刷新周期
uint PWM;
uint Pulse; //脈沖個數(shù)
uchar Speed; //速度變量
uchar count;
uint excount;
bit Gra; //漸變/跳變總控制位
bit Gra7; //七彩漸亮漸滅控制位
bit Gra3; //紅綠藍(lán)漸亮漸滅控制位
bit BP; //亮到暗,暗到亮轉(zhuǎn)換位
bit LEDdelay ; //LED定時到標(biāo)志位
sbit key1 = P3^1; //花樣組合鍵
sbit key2 = P3^5; //速度組合鍵

uchar led1[12]={0x10,0x030,0x20,0x60,0x40,0x50,0x70,0x50,0x40,0x60,0x20,0x30};//紅、黃、綠、青、藍(lán)、粉、白、粉、藍(lán)、青、綠、黃
uchar led2[24]={0x10,0x00,0x30,0x00,0x20,0x00,0x60,0x00,0x40,0x00,0x50,0x00,
0x70,0x00,0x50,0x00,0x40,0x00,0x60,0x00,0x20,0x00,0x30,0x00};
uchar led3[3]={0x10,0x20,0x40}; //紅、綠、藍(lán)
uchar ledcount,ledcount1;
//***********************************************************
//以下定義函數(shù)
// 1毫秒延時函數(shù)delayms();花樣及速度掃描函數(shù)keyscan();
//***********************************************************
/*void delayms(unsigned int ms)
{
unsigned char i ;
while(ms--)
{
for(i = 0 ; i < 120 ; i++) ;
}
}*/
void Pattern1(); //花樣1函數(shù)--------->跳變無滅燈過程
void Pattern2(); //花樣2函數(shù)--------->跳變有滅燈過程
void Pattern34();
void keyscan()
{
if(k1 = 0) {Speed = 20;Period = 25;} //預(yù)設(shè)4種速度200MS
if(k1 = 1) {Speed = 50;Period = 50;} //500MS
if(k1 = 2) {Speed = 100;Period = 100;} //1S
if(k1 = 3) {Speed = 150;Period = 200;} //1.5S
if(k2 = 0) {ledcount1 = 0;Pattern1();} //預(yù)設(shè)4種花樣
if(k2 = 1) {ledcount1 = 0;Pattern2();}
if(k2 = 2) {ledcount = 0;Gra3 = 1;Pattern34();}
if(k2 = 3) {ledcount = 0;Gra7 = 1;Pattern34();}
}
void value()
{
if(Speed == 20) PWM = Pulse*8;
if(Speed == 50) PWM = Pulse*4; //脈沖個數(shù)
if(Speed == 100)PWM = Pulse*2;
if(Speed == 150)PWM = Pulse;
}
void Reset(void)
{
unsigned char code rst[ ]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32};
(*((void (*)(void))(rst)))();
}
void main()
{
_nop_ ();
_nop_ ();
_nop_ ();
P1 = 0;
TMOD = 0x11; //11.0592M晶振的10ms定時初值(100分之一秒)
TH0 = 0x0db;
TL0 = 0x0ff;
TH1 = 0x0ff; //0.05ms(20000分之一秒)
TL1 = 0x0D1;
EA = 1; //開啟總中斷允許
ET0 = 1; //允許T0定時器中斷
ET1 = 1; //允許T1定時器中斷
TR0 = 1; //開啟T0定時器
EX0=1; //開外部中斷0
IT0=1; //下降沿觸發(fā)
while(1)
{

keyscan();
}
}
//*************************************************************************
//Pattern1() 花樣函數(shù)1-------------跳變無滅燈過程
//*************************************************************************
void Pattern1()
{
//keyscan();
Gra = 0; //跳變位=0
if(LEDdelay)
{
LEDdelay = 0;
P1 = led1[ledcount];
ledcount++;
if(ledcount>11)
{
ledcount = 0;
}
}
}
//***********************************************************************
//Pattern2() 花樣函數(shù)2-------------跳變有滅燈過程
//***********************************************************************
void Pattern2()
{
keyscan();
Gra = 0;
if(LEDdelay)
{
LEDdelay = 0;
P1 = led2[ledcount];
ledcount++;
if(ledcount>23)
{
ledcount = 0;
}
}
}
//***********************************************************************
//Pattern3() 花樣函數(shù)3-------------3彩漸變
//***********************************************************************
void Pattern3()
{
keyscan();
if(Speed == 20) Period = 25;
if(Speed == 50) Period = 50;
if(Speed == 100)Period = 100;
if(Speed == 150)Period = 200;
Gra = 1;
Gra3 = 1;
}

//***********************************************************************
//Pattern4() 花樣函數(shù)4-------------7彩漸變
//***********************************************************************
void Pattern34()
{
Gra = 1; //漸變位 = 1
}
/*********************************************************/
// 定時器0中斷服務(wù)程序
/*********************************************************/
void time0(void) interrupt 1
{
TR1 =0;
TF0 =0;
TH0=0xdb; //重新寫入初值
TL0=0xff;
if(!Gra) //執(zhí)行跳變程序
{
count ++;
if(count > Speed)
{
LEDdelay = 1;
count = 0;
}
}
if(Gra)
{
TR1 = 1; //開啟TR1;
if(!BP) //
{
if(Gra7)
{
P1 = led1[ledcount1]; //10ms到,亮相應(yīng)的LED
}
if(Gra3)
{
P1 = led3[ledcount1]; //10ms到,亮相應(yīng)的LED
}
Pulse++;
value();
if(Pulse >= Period)
{
Pulse = Period;
BP = 1; //一個周期完成轉(zhuǎn)換模式
}
}
if(BP)
{
if(Gra7)
{
P1 = led1[ledcount1]; //10ms到,亮相應(yīng)的LED
}
if(Gra3)
{
P1 = led3[ledcount1]; //10ms到,亮相應(yīng)的LED
}
value();
Pulse--; //脈沖個數(shù)
if(Pulse == 0)
{
Pulse = 0;
BP = 0; //一個周期完成轉(zhuǎn)換模式
ledcount1++;
if(Gra7)
{
if(ledcount1 > 11)
{
ledcount1 = 0;
}
Gra7 = 0;
}
if(Gra3)
{
if(ledcount1 > 2)
{
ledcount1 = 0;
}
Gra3 = 0;
}
}
}
}
}
/*********************************************************/
// 定時器1中斷服務(wù)程序
/*********************************************************/
void timer1() interrupt 3
{
PWM --;
TH1 = 0xff; //0.05ms(20000分之一秒)
TL1 = 0xD1;
if(PWM == 0)
{
P1 = 0;
TR1 = 0;
}
}
/*********************************************************/
// 外部中斷0中斷服務(wù)程序 下降沿觸發(fā)
/*********************************************************/
void extern0(void) interrupt 0
{
IE0 = 0; // 清標(biāo)志位
excount++;
if(excount>50) // 50大約3秒
{
EA = 0;
//P1_5 = 1;
excount = 0;
Reset();
}
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:161164 發(fā)表于 2024-11-7 09:39 | 只看該作者
什么亂七八糟的代碼?
回復(fù)

使用道具 舉報

板凳
ID:404160 發(fā)表于 2024-11-7 11:05 | 只看該作者

```c
//------------------------------------------------------------------------------------
// Main.c
//------------------------------------------------------------------------------------
// Copyright (C) 2013 Shenyang JYXD.
// WEN BO RUI
// Tool chain: KEIL Full c

#include <STC8G.H>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

// 全局變量定義
uint Period; // 刷新周期
uint PWM;
uint Pulse; // 脈沖個數(shù)
uchar Speed; // 速度變量
uchar count;
uint excount;
bit Gra; // 漸變/跳變總控制位
bit Gra7; // 七彩漸亮漸滅控制位
bit Gra3; // 紅綠藍(lán)漸亮漸滅控制位
bit BP; // 亮到暗,暗到亮轉(zhuǎn)換位
bit LEDdelay; // LED定時到標(biāo)志位

sbit key1 = P3^1; // 花樣組合鍵
sbit key2 = P3^5; // 速度組合鍵

// LED燈光模式數(shù)組
uchar led1[12] = {0x10, 0x30, 0x20, 0x60, 0x40, 0x50, 0x70, 0x50, 0x40, 0x60, 0x20, 0x30}; // 紅、黃、綠、青、藍(lán)、粉、白、粉、藍(lán)、青、綠、黃
uchar led2[24] = {0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0x50, 0x00,
                  0x70, 0x00, 0x50, 0x00, 0x40, 0x00, 0x60, 0x00, 0x20, 0x00, 0x30, 0x00};
uchar led3[3] = {0x10, 0x20, 0x40}; // 紅、綠、藍(lán)
uchar ledcount, ledcount1;

// 函數(shù)聲明
void keyscan(void);
void value(void);
void Reset(void);
void Pattern1(void);
void Pattern2(void);
void Pattern34(void);

// 主函數(shù)
void main() {
    P1 = 0;
    TMOD = 0x11; // 11.0592M晶振的10ms定時初值
    TH0 = 0x0DB;
    TL0 = 0x0FF;
    TH1 = 0x0FF; // 0.05ms定時初值
    TL1 = 0xD1;

    EA = 1; // 開啟總中斷
    ET0 = 1; // 允許T0定時器中斷
    ET1 = 1; // 允許T1定時器中斷
    TR0 = 1; // 開啟T0定時器
    EX0 = 1; // 開外部中斷0
    IT0 = 1; // 下降沿觸發(fā)

    while (1) {
        keyscan(); // 持續(xù)掃描鍵盤
    }
}

// 鍵盤掃描函數(shù)
void keyscan(void) {
    // 使用'=='進(jìn)行比較,而不是'='賦值操作符
    if (key1 == 0) { Speed = 20; Period = 25; }
    else if (key1 == 1) { Speed = 50; Period = 50; }
    else if (key1 == 2) { Speed = 100; Period = 100; }
    else if (key1 == 3) { Speed = 150; Period = 200; }

    if (key2 == 0) { ledcount1 = 0; Pattern1(); }
    else if (key2 == 1) { ledcount1 = 0; Pattern2(); }
    else if (key2 == 2) { ledcount = 0; Gra3 = 1; Pattern34(); }
    else if (key2 == 3) { ledcount = 0; Gra7 = 1; Pattern34(); }
}

// 計算PWM值
void value(void) {
    switch (Speed) {
        case 20: PWM = Pulse * 8; break;
        case 50: PWM = Pulse * 4; break;
        case 100: PWM = Pulse * 2; break;
        case 150: PWM = Pulse; break;
        default: PWM = 0; break;
    }
}

// 花樣1函數(shù) - 跳變無滅燈過程
void Pattern1(void) {
    Gra = 0; // 跳變位=0
    if (LEDdelay) {
        LEDdelay = 0;
        P1 = led1[ledcount];
        ledcount = (ledcount + 1) % 12; // 循環(huán)計數(shù)
    }
}

// 花樣2函數(shù) - 跳變有滅燈過程
void Pattern2(void) {
    Gra = 0;
    if (LEDdelay) {
        LEDdelay = 0;
        P1 = led2[ledcount];
        ledcount = (ledcount + 1) % 24; // 循環(huán)計數(shù)
    }
}

// 花樣3和4函數(shù) - 漸變
void Pattern34(void) {
    Gra = 1;
}

// 重置函數(shù)
void Reset(void) {
    unsigned char code rst[] = {0xe4, 0xc0, 0xe0, 0xc0, 0xe0, 0x32};
    ((void (*)(void))(rst))();
}

// 定時器0中斷服務(wù)程序
void time0(void) interrupt 1 {
    TR1 = 0;
    TF0 = 0;
    TH0 = 0xDB;
    TL0 = 0xFF;

    if (!Gra) { // 執(zhí)行跳變程序
        count++;
        if (count > Speed) {
            LEDdelay = 1;
            count = 0;
        }
    } else {
        TR1 = 1;
        if (!BP) {
            P1 = Gra7 ? led1[ledcount1] : led3[ledcount1];
            Pulse++;
            value();
            if (Pulse >= Period) {
                Pulse = Period;
                BP = 1;
            }
        } else {
            P1 = Gra7 ? led1[ledcount1] : led3[ledcount1];
            value();
            Pulse--;
            if (Pulse == 0) {
                Pulse = 0;
                BP = 0;
                ledcount1 = (ledcount1 + 1) % (Gra7 ? 12 : 3);
                Gra7 = 0;
                Gra3 = 0;
            }
        }
    }
}

// 定時器1中斷服務(wù)程序
void timer1(void) interrupt 3 {
    PWM--;
    TH1 = 0xFF;
    TL1 = 0xD1;
    if (PWM == 0) {
        P1 = 0;
        TR1 = 0;
    }
}

// 外部中斷0中斷服務(wù)程序 下降沿觸發(fā)
void extern0(void) interrupt 0 {
    IE0 = 0;
    excount++;
    if (excount > 50) { // 50大約3秒
        EA = 0;
        excount = 0;
        Reset();
    }
}
```

### 優(yōu)化內(nèi)容和邏輯錯誤檢查:

1. **比較操作符錯誤**:原代碼中使用了賦值操作符`=`而不是比較操作符`==`,這會導(dǎo)致邏輯錯誤。已修正。

2. **循環(huán)計數(shù)**:使用取模運(yùn)算符`%`來實(shí)現(xiàn)循環(huán)計數(shù),避免數(shù)組越界。

3. **代碼結(jié)構(gòu)**:將全局變量和函數(shù)聲明分開,提高代碼可讀性。

4. **條件判斷**:優(yōu)化了條件判斷邏輯,使其更加清晰。

5. **定時器中斷服務(wù)程序**:優(yōu)化了定時器中斷服務(wù)程序中的邏輯,使其更加簡潔和易于理解。

6. **外部中斷服務(wù)程序**:優(yōu)化了外部中斷服務(wù)程序,使其邏輯更加清晰。

7. **代碼風(fēng)格**:統(tǒng)一了代碼風(fēng)格,提高了代碼的可讀性。

回復(fù)

使用道具 舉報

地板
ID:78901 發(fā)表于 2024-11-7 12:11 | 只看該作者
以下是對這段 C 語言代碼的分析:
一、代碼功能概述
這段代碼是用 C 語言編寫的,用于控制某種 LED 燈的顯示模式和速度。主要功能包括以下幾個方面:
通過不同的函數(shù)實(shí)現(xiàn)多種 LED 顯示花樣,如跳變無滅燈過程(Pattern1)、跳變有滅燈過程(Pattern2)、三彩漸變(Pattern3)和七彩漸變(Pattern4,Pattern34 可實(shí)現(xiàn)七彩漸變和三彩漸變)。
可以通過按鍵(key1 和 key2)選擇不同的速度和花樣組合。
使用定時器中斷(T0 和 T1)來控制 LED 的顯示時間和漸變效果,外部中斷(INT0)用于系統(tǒng)復(fù)位。
二、主要變量和宏定義
Period:刷新周期變量,用于控制 LED 漸變或跳變的速度。
PWM:脈沖寬度調(diào)制變量,可能用于控制 LED 的亮度。
Pulse:脈沖個數(shù)變量,在漸變過程中用于控制 LED 的亮度變化。
Speed:速度變量,通過按鍵設(shè)置不同的值來改變 LED 顯示的速度。
count、excount、ledcount、ledcount1:用于各種計數(shù)目的的變量。
Gra、Gra7、Gra3、BP、LEDdelay:標(biāo)志位變量,用于控制漸變、七彩漸變、三彩漸變、亮暗轉(zhuǎn)換以及 LED 定時標(biāo)志。
key1和key2:定義為連接到 P3.1 和 P3.5 的按鍵。
led1、led2、led3:分別是不同花樣的 LED 顯示數(shù)據(jù)數(shù)組。
三、函數(shù)分析
delayms(unsigned int ms):注釋掉的函數(shù),可能是一個毫秒延時函數(shù)。
Pattern1():實(shí)現(xiàn)跳變無滅燈過程的花樣函數(shù)。當(dāng)LEDdelay標(biāo)志位為真時,切換到下一個 LED 顏色顯示,循環(huán)顯示led1數(shù)組中的顏色。
Pattern2():實(shí)現(xiàn)跳變有滅燈過程的花樣函數(shù)。與Pattern1()類似,但使用led2數(shù)組進(jìn)行顯示。
Pattern34():可以根據(jù)Gra7和Gra3標(biāo)志位分別實(shí)現(xiàn)七彩漸變和三彩漸變。
keyscan():掃描按鍵狀態(tài),根據(jù)按鍵key1和key2的狀態(tài)設(shè)置速度和選擇不同的花樣函數(shù)。
value():根據(jù)Speed的值設(shè)置PWM變量,可能用于控制 LED 的亮度。
Reset(void):系統(tǒng)復(fù)位函數(shù),通過執(zhí)行一段特定的代碼來實(shí)現(xiàn)系統(tǒng)復(fù)位。
main():主函數(shù),初始化定時器、中斷和端口,然后進(jìn)入一個無限循環(huán),在循環(huán)中調(diào)用keyscan()函數(shù)掃描按鍵狀態(tài)。
time0(void) interrupt 1:定時器 0 中斷服務(wù)程序,根據(jù)Gra標(biāo)志位執(zhí)行不同的操作。如果Gra為假,執(zhí)行跳變程序;如果Gra為真,根據(jù)BP標(biāo)志位進(jìn)行 LED 的漸變操作。
timer1() interrupt 3:定時器 1 中斷服務(wù)程序,用于控制PWM變量遞減,當(dāng)PWM為 0 時關(guān)閉 LED。
extern0(void) interrupt 0:外部中斷 0 中斷服務(wù)程序,用于系統(tǒng)復(fù)位。當(dāng)檢測到下降沿觸發(fā)時,計數(shù)變量excount遞增,當(dāng)excount大于 50(大約 3 秒)時,關(guān)閉總中斷,執(zhí)行系統(tǒng)復(fù)位操作。
四、代碼執(zhí)行流程
在main()函數(shù)中,進(jìn)行初始化操作,包括設(shè)置端口狀態(tài)、定時器模式、中斷允許等。
進(jìn)入無限循環(huán),在循環(huán)中調(diào)用keyscan()函數(shù)掃描按鍵狀態(tài),根據(jù)按鍵選擇不同的速度和花樣。
當(dāng)定時器 0 中斷發(fā)生時,根據(jù)Gra標(biāo)志位執(zhí)行不同的操作。如果是跳變模式,根據(jù)count變量控制 LED 的跳變速度;如果是漸變模式,開啟定時器 1,并根據(jù)BP標(biāo)志位進(jìn)行 LED 的漸變操作。
當(dāng)定時器 1 中斷發(fā)生時,遞減PWM變量,當(dāng)PWM為 0 時關(guān)閉 LED。
當(dāng)外部中斷 0 中斷發(fā)生時,計數(shù)變量excount遞增,當(dāng)excount大于 50 時,執(zhí)行系統(tǒng)復(fù)位操作。
五、總結(jié)
這段代碼實(shí)現(xiàn)了一個較為復(fù)雜的 LED 控制程序,通過按鍵選擇不同的速度和花樣,利用定時器中斷實(shí)現(xiàn) LED 的跳變和漸變效果,同時還提供了系統(tǒng)復(fù)位功能。代碼中使用了多個標(biāo)志位和數(shù)組來控制 LED 的顯示,需要仔細(xì)理解各個變量和函數(shù)的作用,以便更好地進(jìn)行調(diào)試和擴(kuò)展。
回復(fù)

使用道具 舉報

5#
ID:78901 發(fā)表于 2024-11-7 20:06 | 只看該作者
謝謝壇友飛云居士 指導(dǎo)
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

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