⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于WINBOND单片机W78E516B的最小系统源代码.通过UART具有BOOTLOAD功能.开发环境为KEIL C51.
💻 C
字号:
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <intrins.h>
#include <absacc.h>

#include "78e516.h"
#include "io.h"
#include "global.h"
#include "serial.h"
#include "event.h"
#include "at24c16.h"
#include "ds1307.h"

sbit LCD_CS    = P2^2;
sbit LCD_RST   = P3^5;
#define LCD_DATA    0x8000
#define LCD_CTRL    0x8200

void Lcd_Reset(void)
{
    LCD_RST = 0;
    _nop_();
    _nop_();
    LCD_RST = 1;
}
#if 0
#define Lcd_Ctrl(v) {_nop_(); _nop_(); XBYTE[LCD_CTRL] = v; _nop_(); _nop_(); _nop_();}
#define Lcd_Data(v) XBYTE[LCD_DATA] = v
#else
void Lcd_Ctrl(U8 v)
{
    while ((XBYTE[LCD_CTRL] & 0x03) != 0x03);
    XBYTE[LCD_CTRL] = v;
}

void Lcd_Data(U8 v)
{
    XBYTE[LCD_DATA] = v;
}
#endif
extern void UpdateLcd(U8 v);
void InitLcd(void)
{
    U8 i,j;

    // Text Home 0000
    Lcd_Data(0x00);
    Lcd_Data(0x00);
    Lcd_Ctrl(0x40);
    // Graphic Home 0400
    Lcd_Data(0x00);
    Lcd_Data(0x04);
    Lcd_Ctrl(0x42);
    // Text Area 40 Cols
    Lcd_Data(30);
    Lcd_Data(0x00);
    Lcd_Ctrl(0x41);
    // Graphic Area 40 Cols
    Lcd_Data(30);
    Lcd_Data(0x00);
    Lcd_Ctrl(0x43);
    // Mode set
    Lcd_Ctrl(0x80); // OR Mode,Intercal Char
    // Offset set
    Lcd_Data(0x02);
    Lcd_Data(0x00);
    Lcd_Ctrl(0x22);
    // Display Mode
//    Lcd_Ctrl(0x94); // Text On,Graphic Off,Cursor Off
    Lcd_Ctrl(0x98); // Text Off,Graphic On,Cursor Off
//    Lcd_Ctrl(0x9c); // Text On,Graphic On,Cursor Off
    // Set Text
    Lcd_Data(0x00);
    Lcd_Data(0x00);
    Lcd_Ctrl(0x24); // Address = 0x0000(Inc)
    Lcd_Ctrl(0xb0); // Auto write
    for (i=0; i<16; i++)
    {
        Lcd_Data(i%10+'0'-' ');
        for (j=0; j<29; j++)
        {
            Lcd_Data(j+'A'-' ');
        }
    }
    Lcd_Ctrl(0xb2); // Auto reset
    UpdateLcd(0x80);
}

void UpdateLcd(U8 v)
{
    U8 i,j,v1;

    // Set Graphic
    Lcd_Data(0x00);
    Lcd_Data(0x04);
    Lcd_Ctrl(0x24); // Address = 0x0400(Inc)
    Lcd_Ctrl(0xb0); // Auto write
    for (i=0; i<136; i++)
    {
        v1 = v << i%8;
        if (v1 == 0)
        {
            v1 = ((U16)v << i%8) >> 8;
        }
        for (j=0; j<30; j++)
        {
            Lcd_Data(v1);
        }
    }
    Lcd_Ctrl(0xb2); // Auto reset
}

void delayms(U8 value)
{
    msCountDown = value + 1;

    while(msCountDown) pollint();
}

/*
函数    串口切换到PC
*/
void UartToPc(void)
{
    RTCWrite(RTC_CTRL,0x00);
//    COMSLT = 0;
}

/*
函数    初始化CPU寄存器
*/
void initcpu(void)
{
    // 初始化定时器2,定时器2用于波特率发生器
    // 波特率 = 震荡频率(18.432M)/(32*(65536-[RCAP2H,RCAP2L]))
    TxEmpty = 1;
    SetBaudRate(_B9600);
    T2CON = 0x34;

    // 设定串口工作:8位数据,1位起始位,1位停止位
    SCON = 0x50;

    // 初始化定时器0工作于模式2,8位自动载入定时器
    // 初始化定时器1工作于模式1,16位定时器
    TH0 = 0x40;
    TMOD = 0x12;
    TCON = 0x50;

    // 控制中断优先级和中断允许
    IP = 0x08;                      // 定时器1工作于高优先级
    IE = 0x9a;                      // 允许串口,定时器0,1中断
}

/*
函数    定时查询程序
*/
void pollint(void)
{
    if (CheckSerial() == '0')
    {
        InitLcd();
        putchar('*');
    }
    if (!pollintack) return;
    pollintack = 0;
    if (--_msCount == 0)
    {
        _msCount = 10;
        if (--_10msCount == 0)
        {
            _10msCount = 10;
            if (--_100msCount == 0)
            {
                _100msCount = 10;
            }
        }
    }
    if (msCountDown > 0) msCountDown--;

    if (RxTimeout > 0)
    {
        if (--RxTimeout == 0)
        {
            RxBusy = 1;
            OnLinetimeout = 5;
        }
    }
    switch(_msCount)                        // 以下1-10每10毫秒执行一次
    {
        case 1:
            ScanKey();
            break;
        case 2:
            pushevent(ev10MS);
            break;
        case 3:
            break;
        case 4:
            break;
        case 5:
            break;
        case 6:
            break;
        case 7:
            break;
        case 8:
            break;
        case 9:
            break;
        default:
            switch(_10msCount)              // 以下1-10每100毫秒执行一次
            {
                case 1:
                    pushevent(ev100MS);
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    break;
                case 5:
                    break;
                case 6:
                    break;
                case 7:
                    break;
                case 8:
                    break;
                case 9:
                    break;
                default:
                    switch(_100msCount)     // 以下1-10每1秒执行一次
                    {
                        case 1:
                            pushevent(ev1SEC);
                            break;
                        case 2:
                            if (OnLinetimeout)
                            {
                                if (--OnLinetimeout == 0) SetBaudRate(_B9600);
                            }
                            break;
                        case 3:
                            break;
                        case 4:
                            break;
                        case 5:
                            break;
                        case 6:
                            break;
                        case 7:
                            break;
                        case 8:
                            break;
                        case 9:
                            break;
                        default:
                            break;
                    }
                    break;
            }
            break;
    }
}

/*
函数    系统初始化程序
*/
void MainReset(void)
{
    _msCount = _10msCount = _100msCount = 10;
    initcpu();
    UartToPc();
    initRTC();          // 初始化RTC
}

/*
函数    主函数,函数先完成初始化动作
*/
void mainfunc(U8 para)
{
    U16 v;
    para = 0x01;
    v = 0x01;
    MainReset();

    Lcd_Reset();
    InitLcd();
    while(1)
    {
        pollint();
        switch(readevent())
        {
            case ev1SEC:
                break;
            case ev100MS:
                // Graphic Home 0400
                para=(para+1)%8;
                v = para*30+0x400;
                Lcd_Data(v%0x100);
                Lcd_Data(v/0x100);
                Lcd_Ctrl(0x42);
                break;
            case ev10MS:
                break;
            case evNON:
                Read24c04(NULL,0,1);
                Write24c04(NULL,0,1);
                break;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -