国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

大一電賽:51單片機(jī)(狀態(tài)機(jī)編程)——控制外部開(kāi)關(guān)(繼電器)達(dá)到自定義輸出波

這篇具有很好參考價(jià)值的文章主要介紹了大一電賽:51單片機(jī)(狀態(tài)機(jī)編程)——控制外部開(kāi)關(guān)(繼電器)達(dá)到自定義輸出波。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

題目來(lái)源于某雙流一大學(xué)第八屆“電協(xié)杯”電子設(shè)計(jì)(校賽)

大一C組:自定義信號(hào)發(fā)生器

隊(duì)伍名稱:擺爛三人組

下文有對(duì)相應(yīng)軟件和硬件的實(shí)現(xiàn)進(jìn)行介紹

電子設(shè)計(jì)大賽編程,51單片機(jī),電賽,嵌入式,51單片機(jī),單片機(jī),嵌入式硬件,硬件工程,Powered by 金山文檔
電子設(shè)計(jì)大賽編程,51單片機(jī),電賽,嵌入式,51單片機(jī),單片機(jī),嵌入式硬件,硬件工程,Powered by 金山文檔

復(fù)盤電賽(軟件部分)

讀題方面

  • 定時(shí)的基礎(chǔ)單位是1ms?。?!

  • 模式二中自定義輸出波,不僅僅是控制每個(gè)波在周期的輸出占比(時(shí)間),還要能夠定義三個(gè)波的輸出順序(不一定是先輸出正弦,后方波,最后三角波)。

  • 不是通過(guò)單片機(jī)輸出波形。

  • 應(yīng)當(dāng)軟件項(xiàng)目開(kāi)發(fā)前應(yīng)當(dāng)畫好結(jié)構(gòu)流程圖(狀態(tài)機(jī))再根據(jù)狀態(tài)機(jī)線路流程依次封裝相應(yīng)的功能,使邏輯顯得更加清晰、縝密,同時(shí)開(kāi)發(fā)效率也會(huì)大為提高

整個(gè)電賽過(guò)程吸取的教訓(xùn)

【反思】在這次的軟件開(kāi)發(fā)中,因?yàn)樵诔跗跊](méi)有規(guī)劃好完整的流程圖,主函數(shù)中的一些代碼存在冗余的情況,并且前期開(kāi)發(fā)邏輯混亂,一直在修改代碼邏輯,導(dǎo)致浪費(fèi)了很多時(shí)間】

【本次電賽未提前規(guī)劃流程圖造成的不便】在電賽驗(yàn)收的前一天晚上才發(fā)現(xiàn)一個(gè)非常容易忽略的說(shuō)明:“定時(shí)時(shí)間的基本單位為1ms”。雖然在定時(shí)器0的模塊中只需要把對(duì)應(yīng)的參數(shù)由1000ms改為1ms即可實(shí)現(xiàn)單位重置,但是前面許多LCD顯示的內(nèi)容都需要要重新編寫,因?yàn)?span id="n5n3t3z" class="kdocs-color" style="background-color:#FBF5B3;">這些顯示內(nèi)容并沒(méi)有做整合封裝,很不便于修改!!當(dāng)時(shí)為了程序的穩(wěn)定運(yùn)行沒(méi)有對(duì)此處做更改,讓整個(gè)軟件在電賽中沒(méi)有起到得拓展分的作用

軟件部分

實(shí)現(xiàn)原理:編寫51單片機(jī)狀態(tài)機(jī),通過(guò)定時(shí)器0來(lái)控制三個(gè)外接引腳(P2^0-P2^2)的高低電平的時(shí)間以達(dá)到自定義輸出波的目的

WARMING

聲明在前:

軟件中的LCD顯示還未改動(dòng),還缺少在模式二下輸出順序可選的狀態(tài)機(jī)模塊,該代碼僅作為思路指引,沒(méi)有做到完全正確!?。?/span>

main.c代碼仍然存在多出紕漏亟待修改,請(qǐng)多包含(題主正忙于學(xué)習(xí)stm32,還沒(méi)有時(shí)間來(lái)修正代碼,如果這篇文章閱讀量大于500,請(qǐng)?jiān)谠u(píng)論區(qū)踢題主一腳)

  • 使用到的外設(shè):LCD1602顯示屏

注意事項(xiàng):

八位數(shù)據(jù)線依次接入外部引腳P1^0-P1^7

sbit LCD_RS=P2^6;

sbit LCD_RW=P2^5;

sbit LCD_EN=P2^7

LCD1602.c
#include <REG52.H>

//引腳配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P1

//函數(shù)定義:
/**
  * @brief  LCD1602延時(shí)函數(shù),12MHz調(diào)用可延時(shí)1ms
  * @param  無(wú)
  * @retval 無(wú)
  */
void LCD_Delay()
{
    unsigned char i, j;

    i = 2;
    j = 239;
    do
    {
        while (--j);
    } while (--i);
}

/**
  * @brief  LCD1602寫命令
  * @param  Command 要寫入的命令
  * @retval 無(wú)
  */
void LCD_WriteCommand(unsigned char Command)
{
    LCD_RS=0;
    LCD_RW=0;
    LCD_DataPort=Command;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602寫數(shù)據(jù)
  * @param  Data 要寫入的數(shù)據(jù)
  * @retval 無(wú)
  */
void LCD_WriteData(unsigned char Data)
{
    LCD_RS=1;
    LCD_RW=0;
    LCD_DataPort=Data;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602設(shè)置光標(biāo)位置
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @retval 無(wú)
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
    if(Line==1)
    {
        LCD_WriteCommand(0x80|(Column-1));
    }
    else if(Line==2)
    {
        LCD_WriteCommand(0x80|(Column-1+0x40));
    }
}

/**
  * @brief  LCD1602初始化函數(shù)
  * @param  無(wú)
  * @retval 無(wú)
  */
void LCD_Init()
{
    LCD_WriteCommand(0x38);//八位數(shù)據(jù)接口,兩行顯示,5*7點(diǎn)陣
    LCD_WriteCommand(0x0c);//顯示開(kāi),光標(biāo)關(guān),閃爍關(guān)
    LCD_WriteCommand(0x06);//數(shù)據(jù)讀寫操作后,光標(biāo)自動(dòng)加一,畫面不動(dòng)
    LCD_WriteCommand(0x01);//光標(biāo)復(fù)位,清屏
}

/**
  * @brief  在LCD1602指定位置上顯示一個(gè)字符
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @param  Char 要顯示的字符
  * @retval 無(wú)
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
    LCD_SetCursor(Line,Column);
    LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置開(kāi)始顯示所給字符串
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  String 要顯示的字符串
  * @retval 無(wú)
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=0;String[i]!='\0';i++)
    {
        LCD_WriteData(String[i]);
    }
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
    unsigned char i;
    int Result=1;
    for(i=0;i<Y;i++)
    {
        Result*=X;
    }
    return Result;
}

/**
  * @brief  在LCD1602指定位置開(kāi)始顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~65535
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~5
  * @retval 無(wú)
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
    }
}

/**
  * @brief  在LCD1602指定位置開(kāi)始以有符號(hào)十進(jìn)制顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:-32768~32767
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~5
  * @retval 無(wú)
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
    unsigned char i;
    unsigned int Number1;
    LCD_SetCursor(Line,Column);
    if(Number>=0)
    {
        LCD_WriteData('+');
        Number1=Number;
    }
    else
    {
        LCD_WriteData('-');
        Number1=-Number;
    }
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
    }
}

/**
  * @brief  在LCD1602指定位置開(kāi)始以十六進(jìn)制顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~0xFFFF
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~4
  * @retval 無(wú)
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i,SingleNumber;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        SingleNumber=Number/LCD_Pow(16,i-1)%16;
        if(SingleNumber<10)
        {
            LCD_WriteData(SingleNumber+'0');
        }
        else
        {
            LCD_WriteData(SingleNumber-10+'A');
        }
    }
}

/**
  * @brief  在LCD1602指定位置開(kāi)始以二進(jìn)制顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~1111 1111 1111 1111
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~16
  * @retval 無(wú)
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
    }
}
LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__

//用戶調(diào)用函數(shù):
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif
  • 同時(shí)使用到了定時(shí)器0

Timer0.c
#include <REGX52.H>

/**
  * @brief  定時(shí)器0初始化,1毫秒@12.000MHz
  * @param  無(wú)
  * @retval 無(wú)
  */
void Timer0_Init(void)
{
    TMOD &= 0xF0;        //設(shè)置定時(shí)器模式
    TMOD |= 0x01;        //設(shè)置定時(shí)器模式
    TL0 = 0x18;        //設(shè)置定時(shí)初值
    TH0 = 0xFC;        //設(shè)置定時(shí)初值
    TF0 = 0;        //清除TF0標(biāo)志
    TR0 = 1;        //定時(shí)器0開(kāi)始計(jì)時(shí)
    ET0=1;
    EA=1;
    PT0=0;
}
Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0_Init(void);

#endif

以及用于矩陣鍵盤的軟件消抖Delay

Delay.c
void Delay(unsigned int xms)
{
    unsigned char i, j;
    while(xms--)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
    }
}
Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

主函數(shù)控制管腳高低電平輸出

軟件控制流程圖
電子設(shè)計(jì)大賽編程,51單片機(jī),電賽,嵌入式,51單片機(jī),單片機(jī),嵌入式硬件,硬件工程,Powered by 金山文檔
main.c封裝代碼框架

//矩陣鍵盤-鍵值判斷

uchar MatrixKey();

//輸出電平模塊

void Main_Otp();//控制輸出引腳

void Out_Ctl_P0(uchar opt);//控制輸出

//模式判斷-狀態(tài)機(jī)

uint OverFLoat(uint num);//防止數(shù)據(jù)溢出:將修改時(shí)間的范圍控制在0-9s

void Mod_Single();//模式一單波的輸出與停止

void Mod_Multi();//模式二三波混合輸出

//狀態(tài)機(jī)-主控系統(tǒng)

void Main_Ctl(); //統(tǒng)帥整個(gè)狀態(tài)機(jī)的狀態(tài)判斷(由按鍵決定狀態(tài)的走向)

void Init_System();//初始化整個(gè)系統(tǒng)

  • Main_Ctl()判斷處于那個(gè)模式下,將工作分配給 Mod_Single()與Mod_Multi()

  • Mod_Single()與Mod_Multi()都會(huì)在調(diào)節(jié)時(shí)間的時(shí)候去調(diào)用防溢出函數(shù)OverFLoat

  • 主函數(shù)main會(huì)調(diào)用一個(gè)【(按鍵)狀態(tài)機(jī)判斷模塊】Main_Ctl()與

【引腳高低電平輸出的模塊】Main_Otp()

  • 將模式一、二的相關(guān)時(shí)間,鍵值,狀態(tài)等參數(shù)均封裝在sta這個(gè)結(jié)構(gòu)體供全局是使用

相應(yīng)參數(shù)介紹:

外部引腳P2^0-P2^2:分別對(duì)應(yīng)繼電器的三個(gè)開(kāi)關(guān),在通過(guò)這三個(gè)開(kāi)關(guān)分別連接到三個(gè)波的電路上

flag_singleOK是模式一中完成

flag_allOK是模式二中完成三個(gè)波的各自輸出時(shí)間

main.c
/**
 * @file main.c
 * @author jUicE_g2R(qq:3406291309)
 * 
 * @brief 通過(guò)按鍵狀態(tài)機(jī)實(shí)現(xiàn)兩個(gè)模式下三個(gè)外接引腳的高低電平輸出
 * @用途:控制C組中三種不同波形的輸出
 * 
 * @version 0.1
 *                     0.1:通過(guò)按鍵控制狀態(tài)機(jī)輸出電平
 *                     0.2:PC端通過(guò)UART串口通信控制狀態(tài)機(jī)輸出電平
 * 
 * @date 2023-3-6(the Latest Correct Time)
 * 
 * @code(state)     已完成兩種模式的調(diào)試
 * 
 * @copyright Copyright (c) 2023
 */
#include <REG52.H>
#include "Timer0.h"
#include "Delay.h"
#include "LCD1602.h"

#define uint unsigned int
#define uchar unsigned char

sbit opt1=P2^0;             //小燈測(cè)試演示波輸出
sbit opt2=P2^1;
sbit opt3=P2^2;

#define Keys P3             //矩陣鍵盤總控鍵

//記錄波形輸入
struct state
{
    //值Val
    uchar wave_val;             //波值
    uchar key_val;          //矩陣鍵盤鍵值
    //控制狀態(tài)
    uchar flag_singleOK;
    uchar flag_otp;           //是否輸出波
    uchar flag_free;          //是否進(jìn)入自由模式
    uchar flag_allOK;            //確定

    //模式一----輸出時(shí)間與停止時(shí)間
    uint wave_otp_t;
    uint wave_stop_t;
    //模式二----各波輸出的時(shí)間0-9
    uint wave_t1;
    uint wave_t2;
    uint wave_t3;
    
    //輸出判斷flag聲明
    uchar flag1_process;
    uchar flag2_process;

} sta={1,0,0,1,0,0,1,1,1,1,1,0,0};

/*-----------子函數(shù)聲明------------*/
//矩陣鍵盤-鍵值判斷
uchar MatrixKey();
//輸出電平模塊
void Main_Otp();
void Out_Ctl_P0(uchar opt);

//模式判斷-狀態(tài)機(jī)
uint OverFLoat(uint num);
void Mod_Single();
void Mod_Multi();
//狀態(tài)機(jī)-主控系統(tǒng)
void Main_Ctl();
void Init_System();

//主函數(shù)
int main(void)
{
    Init_System();
    while(1)
    {
        Main_Otp();
        
        Main_Ctl();
    } 
}

uchar hex[5]={0,0xE,0xD,0xB,0x7};
/*-------------矩陣鍵盤      檢測(cè)算法------------*/
uchar MatrixKey()
{
    uchar row, colu, value, value_temp, i;
    uchar rank;               //矩陣鍵盤鍵號(hào)

    Keys=0x0f;//矩陣鍵盤初始化
    if(Keys!=0x0f)
    {
        Delay(10);//軟件消抖
        if(Keys!=0x0f)
        {
            row=Keys;
            Keys=0xf0;
            colu=Keys;
            value=row+colu;
            
            rank=0;
            value_temp=value%16;
            for( i=1;i<=4;i++)
            {    
                if(value_temp==hex[i])
                rank=(i-1)*4;
            }
            
            value_temp=value/16;                
            for( i=1;i<=4;i++)
            {    
                if(value_temp==hex[i])
                rank+=i;
            }
            while(Keys==0xFF);
        }
        while(Keys!=0xf0);
    }
    else
    {
        rank=0;
    }
    return rank;
}


/*------------電平輸出控制-----------*/
void Out_Ctl_P0(uchar opt)    
{
    switch (opt)
    {
        case 0:
            opt1=0;
            opt2=0;
            opt3=0;
        case 1:
            opt1=1;
            opt2=0;
            opt3=0;
            break;
        case 2:
            opt1=0;
            opt2=1;
            opt3=0;
            break;
        case 3:
            opt1=0;
            opt2=0;
            opt3=1;
        default:
            break;
    }
}

void Main_Otp()         //引腳輸出
{
    if(sta.flag_singleOK==1)
    {
        switch (sta.flag1_process)
        {
            case 1:         //輸出
                Out_Ctl_P0(sta.wave_val);
                break;
            case 2:         //停止
                opt1=0;
                opt2=0;
                opt3=0;
                break;
            default:
                break;
        }
    }

    if(sta.flag_allOK==1)
    {
        switch (sta.flag2_process)
        {
            case 1:         //輸出一號(hào)波
                opt1=1;
                opt2=0;
                opt3=0;
                break;
            case 2:         //輸出二號(hào)波
                opt1=0;
                opt2=1;
                opt3=0;
                break;
            case 3:         //輸出三號(hào)波
                opt1=0;
                opt2=0;
                opt3=1;
                break;
            default:
                break;
        }
    }
    if(sta.flag_otp==0)
    {
        LCD_ShowString(1,4,"STOP");
    }
}

uint OverFLoat(uint num)
{
    if(num>9)
    {
        num=0;
    }
    else if(num<0)
    {
        num=9;
    }
    return num;
}

/*-----------------鍵值處理-----------------*/
void Mod_Single()         //單項(xiàng)調(diào)試
{
    static uchar wave_temp=1;
    static uchar flag_OKTemp=0;
    static uchar i=1;
    uchar wave_t;

    if(sta.key_val==4&i==3)             //選定波,輸出以及停止時(shí)間后輸出
    {
        i=1;        //重置
        sta.flag_singleOK=1;
        LCD_ShowString(1,12,"allOK");
        LCD_ShowString(1,4,"OPT_");
    }
    else
    {
        switch (sta.key_val)
        {
            case 1:
                wave_temp++;
                if(wave_temp>3)
                {
                    wave_temp=1;
                }
                LCD_ShowNum(1,2,wave_temp,1);//顯示波號(hào)
                sta.wave_val=wave_temp;      //記錄wave號(hào):便于停止波后重啟時(shí)波保持停止前的輸出狀態(tài)
                break;

            case 2:            //是否輸出波
                sta.flag_otp++;
                if((sta.flag_otp)>1)
                {
                    sta.flag_otp=0;
                }

                if(sta.flag_otp==0)   //停止輸出波
                {
                    sta.flag_singleOK=0;
                }
                break;
            case 4:
                i++;
                flag_OKTemp=1;
                break;

            case 6:     //輸出時(shí)間
                flag_OKTemp=0;
                switch (i)
                {
                    case 2:
                        wave_t=sta.wave_otp_t+1;
                        sta.wave_otp_t=OverFLoat(wave_t);
                        LCD_ShowNum(1,9,sta.wave_otp_t,1);
                        break;
                    case 3:
                        wave_t=sta.wave_stop_t+1;
                        sta.wave_stop_t=OverFLoat(wave_t);
                        LCD_ShowNum(1,11,sta.wave_stop_t,1);
                        break;
                    default:
                        break;
                }
                break;

            case 7:     //停止時(shí)間
                flag_OKTemp=0;
                switch (i)
                {
                    case 2:
                        wave_t=sta.wave_otp_t-1;
                        sta.wave_otp_t=OverFLoat(wave_t);
                        LCD_ShowNum(1,9,sta.wave_otp_t,1);
                        break;
                    case 3:
                        wave_t=sta.wave_stop_t-1;
                        sta.wave_stop_t=OverFLoat(wave_t);
                        LCD_ShowNum(1,11,sta.wave_stop_t,1);
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }

        if(flag_OKTemp==0)
        {
            LCD_ShowString(1,15,"no");
        }
        else
        {
            LCD_ShowString(1,15,"OK");
        }
    } 
    
}


void Mod_Multi()         //自由模式
{
    static uchar flag_OKTemp=0;
    uint wave_t;
    static uchar i=0;           //調(diào)好三個(gè)波的時(shí)間就可以輸出了

    if(i==3&&sta.key_val==4)       //切換到第三個(gè)波且確定時(shí),開(kāi)始輸出波
    {
        i=1;        //重置
        sta.flag_allOK=1;       //可以輸出波了
        sta.flag_otp=1;         //引腳高電平輸出
        LCD_ShowString(1,12,"allOK");
        LCD_ShowString(1,4,"OPT_");
    }
    else        //選擇波以及波輸出時(shí)間
    {
        switch (sta.key_val)
        {
            case 4:     //每個(gè)波形時(shí)間確定鍵
                flag_OKTemp=1;
                i++;
                break;
            case 5:     //切波:在確定的條件下才能切波
                if(flag_OKTemp==1)
                {
                    sta.wave_val++;
                    if(sta.wave_val>3)
                    {
                        sta.wave_val=1;
                    }
                    flag_OKTemp=0;                      //重置OK值
                    LCD_ShowNum(1,2,sta.wave_val,1);    //切換的波的波號(hào)顯示
                }
                break;

            case 6:     //增加波的時(shí)間
                flag_OKTemp=0;
                switch (sta.wave_val)
                {
                    case 1:
                        wave_t=sta.wave_t1+1;
                        sta.wave_t1=OverFLoat(wave_t);
                        LCD_ShowNum(2,4,sta.wave_t1,1);
                        break;
                    case 2:
                        wave_t=sta.wave_t2+1;
                        sta.wave_t2=OverFLoat(wave_t);
                        LCD_ShowNum(2,9,sta.wave_t2,1);
                        break;
                    case 3:
                        wave_t=sta.wave_t3+1;
                        sta.wave_t3=OverFLoat(wave_t);
                        LCD_ShowNum(2,14,sta.wave_t3,1);
                        break;
                    default:
                        break;
                }
                break;

            case 7:     //減少波的時(shí)間
                flag_OKTemp=0;
                switch (sta.wave_val)
                {
                    case 1:
                        wave_t=sta.wave_t1-1;
                        sta.wave_t1=OverFLoat(wave_t);
                        LCD_ShowNum(2,4,sta.wave_t1,1);
                        break;
                    case 2:
                        wave_t=sta.wave_t2-1;
                        sta.wave_t2=OverFLoat(wave_t);
                        LCD_ShowNum(2,9,sta.wave_t2,1);
                        break;
                    case 3:
                        wave_t=sta.wave_t3-1;
                        sta.wave_t3=OverFLoat(wave_t);
                        LCD_ShowNum(2,14,sta.wave_t3,1);
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        if(flag_OKTemp==0)
        {
            LCD_ShowString(1,15,"no");
        }
        else
        {
            LCD_ShowString(1,15,"OK");
        }

    }
    
}

void Main_Ctl()             //主控模塊
{
    uchar wave_temp=1;

    sta.key_val=MatrixKey();            //獲取矩陣鍵值
    if(sta.key_val!=0)                  //沒(méi)有鍵按下就不進(jìn)入判斷
    {
        if(sta.flag_free==1)
        {
            if(sta.key_val==2)             //在自由模式下任何情況都可以退出
            {
                sta.flag_otp=0;       //停止輸出波
                sta.flag_free=0;      //退出自由調(diào)節(jié)模式
                LCD_ShowChar(2,16,'S');         //還原到單項(xiàng)操作
                LCD_ShowString(1,15,"no");
            }
            else
            {
                Mod_Multi();
            }
        }
        else if(sta.flag_free==0)          //單項(xiàng)輸出波
        {
            LCD_ShowChar(2,16,'S');         //更改模式
            if(sta.flag_otp==0)            //進(jìn)入停止輸出才能調(diào)至自由調(diào)整模式
            {
                if(sta.key_val==3)         //進(jìn)入自由調(diào)整模式
                {
                    sta.flag_free=1;       //此時(shí)波形已經(jīng)停止輸出 
                    LCD_ShowChar(2,16,'M');          //更改模式
                    LCD_ShowString(1,4,"STOP");
                    LCD_ShowString(1,8,"       ");
                    Timer0_Init();                   //重置定時(shí)器0
                    
                    //輸出初始化
                    opt1=0;
                    opt2=0;
                    opt3=0;
                }
            }
            else if(sta.flag_otp==1)      //輸出波
            {
                Mod_Single();
            }
        }
    } 
}

void Init_System()      //初始化系統(tǒng)
{
    Timer0_Init();      //定時(shí)器初始化
    /*屏幕初始化*/
    LCD_Init();

    //第一行演示:    |W1            S|
    LCD_ShowChar(1,1,'W');        //表示所處的波形
    LCD_ShowNum(1,2,1,1);         //波號(hào)
    LCD_ShowString(1,4,"STOP");
    LCD_ShowChar(2,16,'S');       //模式
    //第二行演示:   |W1 1 W2 2 W3 3 no|
    LCD_ShowChar(2,1,'W');
    LCD_ShowNum(2,2,1,1);
    LCD_ShowChar(2,3,':');

    LCD_ShowChar(2,6,'W');
    LCD_ShowNum(2,7,2,1);
    LCD_ShowChar(2,8,':');
    
    LCD_ShowChar(2,11,'W');
    LCD_ShowNum(2,12,3,1);
    LCD_ShowChar(2,13,':');

    LCD_ShowString(1,15,"no");

    LCD_ShowChar(1,10,'|');
    /*引腳輸出輸出初始化*/
//    Out_Ctl_P0(0);     //初始化輸出端口
    opt1=0;
    opt2=0;
    opt3=0;
}

/*定時(shí)器中斷函數(shù)*/
void Timer0_Routine() interrupt 1
{
    static int T0cot1=0;
    static int T0cot2=0;

    TL0 = 0x18;        //設(shè)置定時(shí)初值
    TH0 = 0xFC;        //設(shè)置定時(shí)初值
    if(sta.flag_otp==1)     //控制停止輸出波
    {
        //控制輸出波flag
        if(sta.flag_singleOK==1)
        {    
            if(T0cot1==0)
            {
                sta.flag1_process=1;
            }
            else if(T0cot1==1*sta.wave_otp_t)
            {
                sta.flag1_process=2;
            }
            T0cot1++;
            //重置循化
            if(T0cot1>1*(sta.wave_otp_t+sta.wave_stop_t))
            {
                T0cot1=0;
            }
        }

        if(sta.flag_allOK==1)
        {
            //控制輸出波flag
            if (T0cot2==0)
            {
                sta.flag2_process=1;
            }    
            else if(T0cot2==1*sta.wave_t1)
            {
                sta.flag2_process=2;
            }
            else if(T0cot2==1*(sta.wave_t1+sta.wave_t2))
            {
                sta.flag2_process=3;
            }

            T0cot2++;
            if(T0cot2>1*(sta.wave_t1+sta.wave_t2+sta.wave_t3))        //重置,循環(huán)
            {
                T0cot2=0;
            }
        }
    }
}

硬件部分

  • 波形產(chǎn)生分析

正弦波發(fā)生電路

采用文式橋振蕩電路為基礎(chǔ)產(chǎn)生正弦波,組成為:放大電路、反饋網(wǎng)絡(luò)、選頻網(wǎng)絡(luò)、穩(wěn)幅環(huán)節(jié)

放大電路:

文氏電橋振蕩器采用的是同相放大器,當(dāng)信號(hào)較小時(shí),二極管不導(dǎo)通,放大倍數(shù)為A=1+(RP2+R1)/R8

當(dāng)信號(hào)較大時(shí),二極管導(dǎo)通,放大倍數(shù)為A=1+(RP2+r)/R8,r為R1所對(duì)應(yīng)的匹配電阻。

反饋網(wǎng)絡(luò):

反饋是將輸出信號(hào)的全部或一部分返回至輸入,使輸入信號(hào)改變,而負(fù)反饋是引起輸入信號(hào)減小的一種反饋方式。同向放大器引入負(fù)反饋,使得輸出信號(hào)與輸入信號(hào)比值穩(wěn)定。

選頻網(wǎng)路:

RC帶通濾波器,該電路由高通和低通濾波器組合而成,其中RP1=RP4,C1=C2,頻率為f=1/(2πRC)。

f=1/(2*Π*RC)(RP1 = RP4,C1 = C2),f=1/(2*Π*RP1*C2)。

穩(wěn)幅環(huán)節(jié):

文氏電橋的起振條件是:|AF|>1;但文氏電橋的穩(wěn)幅條件確是:|AF|=1。利用二極管的非線性自動(dòng)調(diào)節(jié)負(fù)反饋的強(qiáng)弱來(lái)控制輸出電壓的恒定。振蕩過(guò)程中D1、D2將交替導(dǎo)通和截止,總有一個(gè)處于正向?qū)顟B(tài)的二極管與R3并聯(lián),由于二極管正向電阻rd隨ud增大而下降,因此負(fù)反饋隨振幅上升而增強(qiáng),也就是說(shuō)A隨振幅增大而下降,直到滿足振幅平衡條件為止。

圖中RP1和RP4可調(diào)節(jié)頻率,RP2可調(diào)節(jié)放大倍數(shù)。

方波發(fā)生電路

利用下行滯回比較器輸出方波,滯回比較器的輸入電壓逐漸增大或者減小時(shí),有兩個(gè)不相等的閾值,其傳輸特性具有滯回曲線的形狀,因此具有很強(qiáng)的抗干擾能力。

uo=土Uz,

RP3調(diào)節(jié)放大倍數(shù)。

電子設(shè)計(jì)大賽編程,51單片機(jī),電賽,嵌入式,51單片機(jī),單片機(jī),嵌入式硬件,硬件工程,Powered by 金山文檔
三角波發(fā)生電路

利用集成運(yùn)放構(gòu)成積分器,然后對(duì)方波信號(hào)進(jìn)行運(yùn)算產(chǎn)生三角波。

R7是防止積分電路飽和的反饋電阻,它的大小需要比R1大兩個(gè)數(shù)量級(jí),這樣就不會(huì)影響積分波形,R7越大三角波越往上。RP3和R5與E1的值決定三角波斜率,因此調(diào)節(jié)RP3可以改變?nèi)遣ǖ姆怠?mark hidden color="red">文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-756471.html

電子設(shè)計(jì)大賽編程,51單片機(jī),電賽,嵌入式,51單片機(jī),單片機(jī),嵌入式硬件,硬件工程,Powered by 金山文檔
  • 軟件與硬件橋接——電路開(kāi)關(guān)設(shè)計(jì)

用繼電器模塊作為開(kāi)關(guān),對(duì)電路三種輸出波形進(jìn)行控制。由于繼電器模塊觸發(fā)電壓為3.3V~5V,進(jìn)而可用控制單片機(jī)引腳輸出的高低電平的方法來(lái)控制繼電器的開(kāi)關(guān),從而實(shí)現(xiàn)對(duì)輸出波形的智能化控制文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-756471.html

三位一體原理圖

電子設(shè)計(jì)大賽編程,51單片機(jī),電賽,嵌入式,51單片機(jī),單片機(jī),嵌入式硬件,硬件工程,Powered by 金山文檔

到了這里,關(guān)于大一電賽:51單片機(jī)(狀態(tài)機(jī)編程)——控制外部開(kāi)關(guān)(繼電器)達(dá)到自定義輸出波的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 51單片機(jī)控制鍵盤

    51單片機(jī)控制鍵盤

    鍵盤是電子系統(tǒng)中人機(jī)對(duì)話的重要組成部分,是人向機(jī)器發(fā)出指令、輸入信息的必須設(shè)備 鍵盤在單片機(jī)應(yīng)用系統(tǒng)中是使用最廣泛的一種數(shù)據(jù) 輸入設(shè)備 。鍵盤是由多個(gè) 按鍵 組成的。 按鍵通常是一種常開(kāi)型開(kāi)關(guān),常態(tài)下按鍵的兩個(gè)觸點(diǎn)處于 斷開(kāi) 狀態(tài),按下按鍵時(shí)它們才閉合

    2024年02月02日
    瀏覽(19)
  • 【藍(lán)橋杯_學(xué)習(xí)_51單片機(jī)】矩陣鍵盤 狀態(tài)機(jī)法

    【藍(lán)橋杯_學(xué)習(xí)_51單片機(jī)】矩陣鍵盤 狀態(tài)機(jī)法

    一.基礎(chǔ)知識(shí) 在鍵盤中按鍵數(shù)量較多時(shí),為了減少I/O口的占用,通常將按鍵排列成矩陣形式 采用逐行或逐列的“掃描”,就可以讀出任何位置按鍵的狀態(tài) 矩陣鍵盤和獨(dú)立按鍵一樣,也需要進(jìn)行消抖處理! 于此補(bǔ)充一下抖動(dòng)的含義: 對(duì)于機(jī)械開(kāi)關(guān),當(dāng)機(jī)械觸點(diǎn)斷開(kāi)、閉合時(shí),

    2023年04月09日
    瀏覽(21)
  • 51單片機(jī)IO口控制

    原理:根據(jù)電路圖,指向IO口的引腳;拉低電平,燈亮、 如圖: [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-Zfco4IjK-1690308697530)(C:/Users/xie19/Pictures/Camera Roll/屏幕截圖 2023-07-19 014128.png)] [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下

    2024年02月15日
    瀏覽(27)
  • 四、51單片機(jī)控制獨(dú)立按鍵

    四、51單片機(jī)控制獨(dú)立按鍵

    按鍵相關(guān)知識(shí)。 1.1、按鍵工作原理 (1)按鍵內(nèi)部是機(jī)械結(jié)構(gòu),也就是內(nèi)部是沒(méi)有電路的。按鍵對(duì)外表現(xiàn)位四個(gè)引腳,但本質(zhì)上只是兩個(gè),引腳是兩兩連在一起的。按鍵按下內(nèi)部引腳導(dǎo)通,松開(kāi)內(nèi)部斷開(kāi)。 (2)電路連接與原理圖中圖標(biāo)。 按鍵一端接地,一端接單片機(jī)IO口。 ?(3)按

    2023年04月14日
    瀏覽(23)
  • 五、51單片機(jī)控制矩陣按鍵

    五、51單片機(jī)控制矩陣按鍵

    1.1、矩陣按鍵原理分析 這里矩陣按鍵為4*4的矩陣按鍵。 (1)矩陣按鍵橫向和縱向分割。 (2)按鍵兩端分別接不同的IO引腳。 (3)按鍵物理作用不變:按下按鍵兩端接通,彈起按鍵兩端斷開(kāi)。 1.2、矩陣按鍵的工作過(guò)程 JP4接P3端口,JP4_8接P3^7...JP4_1接P3^0。 (1)IO端口(P3)先輸出0x0f,按鍵列

    2023年04月20日
    瀏覽(16)
  • 如何使用單片機(jī)點(diǎn)亮LED燈,并使用按鍵控制[51單片機(jī)]

    如何使用單片機(jī)點(diǎn)亮LED燈,并使用按鍵控制[51單片機(jī)]

    首先先看一下我的板子,如果我們板子不相同,可能操作也不太相同 我們就不講底層原理了,直接看,我們可以看到板子上有?8個(gè)LED燈 ? 那這個(gè)8個(gè)LED用什么來(lái)控制呢,我們先看底層的線路圖,所有的LEDD都連接到了P2帶后綴的接口上, 那么只需要操作這幾個(gè)接口的高低電頻,

    2024年02月05日
    瀏覽(29)
  • 51單片機(jī)按鍵控制流水燈

    51單片機(jī)按鍵控制流水燈

    1獨(dú)立按鍵的原理圖 按鍵所對(duì)應(yīng)的引腳為P3的0、1、2、3引腳口,并且這里總共有四個(gè)獨(dú)立按鍵,它們公共的一段都接到了 GND 電源的負(fù)極。這樣我們就知道按鍵上電的默認(rèn)電平為高電平。所以我們只需要控制按鍵按下時(shí)給一個(gè)低電平0,不按下時(shí)默認(rèn)高電平1就行。 ?2按鍵控制

    2024年02月11日
    瀏覽(19)
  • 51單片機(jī)按鍵控制LED亮滅

    51單片機(jī)按鍵控制LED亮滅

    通過(guò)單片機(jī)按鍵控制LED亮滅與傳統(tǒng)電路的物理邏輯不同,在物理邏輯中開(kāi)關(guān)控制電路的通斷來(lái)控制LED的亮滅,而通過(guò)單片機(jī)完成該項(xiàng)目至于要不斷地讀取按鍵所連接IO口的電平來(lái)判斷對(duì)LED連接的IO口輸出的電平即可。 原理圖如下: ?根據(jù)原理圖,我們可以發(fā)現(xiàn)按鍵按下時(shí)P2.1口

    2023年04月18日
    瀏覽(29)
  • 二、51單片機(jī)控制數(shù)碼管

    二、51單片機(jī)控制數(shù)碼管

    (1)數(shù)碼管的外觀: 數(shù)碼管可分為單個(gè)的,聯(lián)排的(2位、4位、8位) (2)數(shù)碼管的作用: 數(shù)碼管是顯示器件,是用來(lái)顯示數(shù)字的。 (1)數(shù)碼管的亮滅是由內(nèi)部的照明LED的亮滅實(shí)現(xiàn)的。 (2)一位數(shù)碼管內(nèi)部有八顆LED燈,利用內(nèi)部的LED燈的亮和滅讓數(shù)碼管顯示不同的數(shù)字。 (1)驅(qū)動(dòng)方法的

    2023年04月09日
    瀏覽(29)
  • 51單片機(jī)-按鍵控制led燈

    51單片機(jī)-按鍵控制led燈

    1.開(kāi)發(fā)環(huán)境介紹 使用C語(yǔ)言,環(huán)境為keil Keil C51是美國(guó)Keil Software公司出品的51系列兼容單片機(jī)C語(yǔ)言軟件開(kāi)發(fā)系統(tǒng),與匯編相比,C語(yǔ)言在功能上、結(jié)構(gòu)性、可讀性、可維護(hù)性上有明顯的優(yōu)勢(shì),因而易學(xué)易用. 什么是單片機(jī) 單片機(jī)(Single-Chip Microcomputer)是一種集成電路芯片,把具

    2024年02月09日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包