lezjin 发表于 2024-5-12 15:48:33

STC8H试验箱学习记录

89C51熟悉一遍了,开始学习8H

lezjin 发表于 2024-5-12 15:51:41

先上试验箱图片,感谢STC。

lezjin 发表于 2024-5-12 15:59:43

本帖最后由 lezjin 于 2024-5-12 16:01 编辑

#include "../STC8H.h"
#include "delay.h"

void main(void)
{
    unsigned char i;
    P6M0 = 0x00; P6M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P40 = 0;

    while(1)
    {
       for(i = 0; i<8; i++)
       {
         P6 = ~(0x01 << i);
         delay_ms(200);
       }
    }

先来个流水灯,成功点亮,查看官方例子,用的是数组查表的方法,感觉查表的方法应该比这个运算要快一些。不过点灯的话就无所谓了。

lezjin 发表于 2024-5-12 16:26:53

第二,定时器

ISP生成的定时器代码中没有开中断,开启EA后不能运行,查看手册和官方例子,ET0没有打开,打开后正常运行。

void Timer0_Init(void)                //1毫秒@11.0592MHz
{
        AUXR |= 0x80;                        //定时器时钟1T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0xCD;                                //设置定时初始值
        TH0 = 0xD4;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
}


#include "../STC8H.h"
#include "stc8h_timer.h"

unsigned int count;

void main(void)
{
    P6M0 = 0x00; P6M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P40 = 0;
    Timer0_Init();
    ET0 = 1;
    EA = 1;
    while (1)
    {
      if(count >= 1000)      //1毫秒@11.0592MHz1000 次为一秒
      {
      count = 0;
      P67 = ~P67;   
      }
    }
}


void Time0_ISR() interrupt   TMR0_VECTOR//定时器0中断函数
{
    count++;
}

lezjin 发表于 2024-5-12 17:55:53

三,数码管

官方的例子数码管编码取反和位选那里(7-位置)不好理解,容易混淆,既然查表了,还要取反再做其他运算,和流水灯的查表就违背了, 这样流水灯还不如用循环。
找了个数码管的原理图,重新编码了一下,显示函数逻辑就清晰了。

#include "../STC8H.h"
#include "stc8h_timer.h"

//共阳数码管编码0-16,最后一个位熄灭状态, 高位 dp g f e d c b a 低位
unsigned char code display_array[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
                                    0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};      

unsigned char code display_we[]={0x7F, 0xbf, 0xdf, 0xef,0xf7, 0xfb, 0xfd, 0xfe};      //位码


typedef struct
{
    unsigned char hour;   //时
    unsigned char minute;    //分
    unsigned char second;   //秒
}Timetype_t;

Timetype_t Time_count = {23, 59, 57};

unsigned int g_scanflag;    //刷新时间标志位
unsigned char g_display_index; //显示位索引
unsigned char Ledbuff;   //显示缓存
bit g_bms;//1毫秒标志

void displayrtc(void)
{
    if(Time_count.hour >= 10)
    {
      Ledbuff =Time_count.hour / 10;
    }
    else
      Ledbuff = 16;//编码数组最后一个,熄灭状态,0xFF

    Ledbuff = Time_count.hour % 10;
    Ledbuff = Time_count.minute / 10;
    Ledbuff = Time_count.minute % 10;
    Ledbuff = Time_count.second / 10;
    Ledbuff = Time_count.second % 10;
}


void rtc (void)
{
    if (++Time_count.second >= 60)
    {
      Time_count.second = 0;
      if (++Time_count.minute >= 60)
      {
            Time_count.minute = 0;
            if (++Time_count.hour >= 24)
            {
                Time_count.hour = 0;
            }
      }
    }
}

void displayscan(void)
{
   P7 = display_we;
   P6 = display_array];
   g_display_index++;
   g_display_index %= 6;
}

void main(void)
{


    P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    Timer0_Init();
    ET0 = 1;
    EA = 1;

    rtc();
    displayrtc();


    while (1)
    {
      if(g_bms)
      {
            g_bms = 0;
            if(++g_scanflag >= 1000)    //1秒刷新一次时间
            {
                g_scanflag = 0;
                rtc();
                displayrtc();
                  
            }
      }
    }
}


void Time0_ISR(void) interrupt   TMR0_VECTOR//定时器0中断函数
{
    displayscan();
    g_bms = 1 ;
}


lezjin 发表于 2024-5-12 18:04:54

可以跑时间了

lezjin 发表于 2024-5-12 19:52:02

四。T0做外部计数器

我只配置了T0,T1同理就没有配置,试的过程中发现   P3.4,P3.5 不使能内部4.1k上拉电阻,也能用,当然还是参考手册,设置为上拉4.1K电阻。
同时注意到初始值都设置为0xff,试了下我把低位改成0XFe,测试现象按两次才会才会进入一次中断。

#include "../STC8H.h"

void main(void)
{
    P0M0 = 0x00; P0M1 = 0x00;
    P1M0 = 0x00; P1M1 = 0x00;
    P2M0 = 0x00; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P5M0 = 0x00; P5M1 = 0x00;
    P6M0 = 0x00; P6M1 = 0x00;
    P7M0 = 0x00; P7M1 = 0x00;

    P3PU = 0x30;            //P3.4,P3.5使能内部4.1K上拉电阻
    P40 = 0;

          AUXR |= 0x80;                        //定时器时钟1T模式
    TMOD = 0;                        //设置定时器模式
    TL0 = 0xff;                              //设置定时初始值
    TH0 = 0xff;                              //设置定时初始值
    TMOD = 0X04;
    TF0 = 0;                              //清除TF0标志
    TR0 = 1;                              //定时器0开始计时
    ET0 = 1;

    INTCLKO &= 0xfe;       //T0不输出时钟

    EA = 1;
    while (1)
    {
      
    }
}


void Time0_ISR(void) interrupt   TMR0_VECTOR//定时器0中断函数
{
    P6= ~P6;
}



lezjin 发表于 2024-6-28 20:08:35

好久没有更新了,今天把写好的例程发一下

lezjin 发表于 2024-6-28 20:15:48

本帖最后由 lezjin 于 2024-6-28 20:26 编辑

五。在时间片调用中增加了一个UART2发送给电脑测试,
void UartInit(void)
{
    COMx_InitDefine uartinfo;
    uartinfo.UART_Mode = UART_8bit_BRTx;
uartinfo.UART_BRT_Use = BRT_Timer2;
    uartinfo.UART_BaudRate = 115200L;
    uartinfo.UART_RxEnable = ENABLE;
    uartinfo.Morecommunicate = ENABLE;
    uartinfo.BaudRateDouble = DISABLE;

    UART_Configuration(UART2, &uartinfo);
   
    NVIC_UART2_Init(ENABLE, Priority_1);   
    UART2_SW(UART2_SW_P46_P47);
}

void testuart2(void)
{
    PrintString2("Test uart2 !\r\n");


配置串口2使用了库函数,在主函数中每5秒调用测试函数

lezjin 发表于 2024-6-28 20:41:05

六。矩阵按键   行列扫描返回端口数值,然后 采用论坛三行代码,返回键值后判断按键简单点灯灭灯测试效果,主函数每20毫秒扫描一次,可以正常点亮熄灭,健壮性有待后续验证。

#define KEY P0

static void KeyDelay(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}

static unsigned char KeyScan()
{
    unsigned char keynum = 0xff ;

      KEY = 0xf0;
      KeyDelay();
      keynum = KEY & 0xf0;

      KEY = 0x0f;
      KeyDelay();
      keynum |= (KEY & 0x0f);
//    keynum = keynum ^ 0xff;
    return keynum;
}


unsigned charKeyVal(void)
{
      static unsigned char s_keyStateLast;
    static unsigned char s_keyStateNow;
    unsigned char keyval=0;
         unsigned char readKeyPort=0;

      readKeyPort = (KeyScan()) ^ 0xff;         //1111 11111
      s_keyStateNow = readKeyPort & (readKeyPort ^ s_keyStateLast);
      s_keyStateLast = readKeyPort;

    keyval = s_keyStateNow;
    return keyval;
}


void MatrixKey(void)
{

    unsigned char key =KeyVal();

    if (key == 0x81)
      P65 = 0;
    if (key== 0x82)
      P65 = 1;
    if (key == 0x84)
      P66 = 0;
    if (key == 0x88)
      P66 = 1;
    if (key == 0x41)
      P67 = 0;
    if (key == 0x42)
      P67 = 1;
}

static Task_t g_task[] =
{
//状态计数重装   函数
{0,20, 20,MatrixKey},
          /* Add new task here */

};



页: [1] 2
查看完整版本: STC8H试验箱学习记录