卐词意不达 · 2021年12月23日

【XR806开发板试用】实时时钟

【XR806开发板试用】spi+ntp+max7219=实时时钟
v2-9eae0f36c02dc4523b98aaf8a02d14f2_1440w.jpg
v2-912c7b4673e54ffc2bc3ae0ee9cbf9c7_r.jpg
xr806-image-20211018163514601.png
PIN 使用
1-5V
11-GND
12-SPI0_MOSI
13-SPI0_CS0
14-SPI0_MISO -未使用
15-SPI0_CLK
接线
xr806----------8位数码管max7219
1-----------------vcc
11----------------gnd
12----------------din
13----------------cs
15----------------clk

nano 是命令行文本编辑工具 纯个人习惯
make 是我当前帐号的名字
cd /home/make/xr806_openharmony/device/xradio/xr806/ohosdemo/
也可cd ~/xr806_openharmony/device/xradio/xr806/ohosdemo/ 即当前登录帐号目录

nano BUILD.gn

group("ohosdemo") {
    deps = [
     "sntp:app_sntp_Test",
    ]
}

ctrl+o 保存

   回车

ctrl+x 退出

创建目录

mkdir sntp
cd sntp
nano BUILD.gn

import("//device/xradio/xr806/liteos_m/config.gni")

static_library("app_sntp_Test") {
   configs = []

   sources = [
      "main.c",
   ]

   cflags = board_cflags

   include_dirs = board_include_dirs
   include_dirs += [
        ".",
        "//utils/native/lite/include",
        "//foundation/communication/wifi_lite/interfaces/wifiservice",
        "//device/xradio/xr806/xr_skylark/include/net/sntp",
         "//base/iot_hardware/peripheral/interfaces/kits",
   ]
}

ctrl+o 保存

   回车

ctrl+x 退出

nano main.c

#include <stdio.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "wifi_device.h"
#include "sntp.h"
#include "iot_gpio.h"
#include "driver/chip/hal_spi.h"
#include "common/framework/platform_init.h"

/* spi */
#define DEMO_SPI_MCLK (48 * 1000 * 1000)
#define DEMO_SPI_CS_LEVEL 0
#define DEMO_SPI_PORT SPI0
#define DEMO_SPI_CS SPI_TCTRL_SS_SEL_SS0
#define DEMO_FLASH_INSTRUCTION_RDID 0x9F /* flash jedec id */

static OS_Thread_t g_main_thread;
static OS_Thread_t g_time_thread;


#define WIFI_DEVICE_CONNECT_AP_SSID "11111111"//wifi名称
#define WIFI_DEVICE_CONNECT_AP_PSK "11111111"//wifi密码

#define SNTP_YEAR_OFFSET (2000)
#define CMD_SYSLOG printf
#define CMD_LOG(flags, fmt, arg...) \
    do                              \
    {                               \
        if (flags)                  \
            CMD_SYSLOG(fmt, ##arg); \
    } while (0)

/*8 DIGITS begin*/
#define NUMBER_OF_DIGITS 8
typedef enum
{
    REG_NO_OP = 0x00,
    REG_DIGIT_0 = 0x01,
    REG_DIGIT_1 = 0x02,
    REG_DIGIT_2 = 0x03,
    REG_DIGIT_3 = 0x04,
    REG_DIGIT_4 = 0x05,
    REG_DIGIT_5 = 0x06,
    REG_DIGIT_6 = 0x07,
    REG_DIGIT_7 = 0x08,
    REG_DECODE_MODE = 0x09,     //译码方式,0x00为不译码,0xff为译码
    REG_INTENSITY = 0x0A,     //显示亮度,取值范围0~f
    REG_SCAN_LIMIT = 0x0B,     // 8位扫描显示,取值范围0x01~0x07
    REG_SHUTDOWN = 0x0C,     //操作方式,0x00为低功耗模式,0x01为正常操作模式
    REG_DISPLAY_TEST = 0x0F, //显示状态,0x00为正常显示,0x01为显示测试
} MAX7219_REGISTERS;

typedef enum
{
    DIGIT_1 = 1,
    DIGIT_2 = 2,
    DIGIT_3 = 3,
    DIGIT_4 = 4,
    DIGIT_5 = 5,
    DIGIT_6 = 6,
    DIGIT_7 = 7,
    DIGIT_8 = 8
} MAX7219_Digits;

typedef enum
{
    NUM_0 = 0x00,
    NUM_1 = 0x01,
    NUM_2 = 0x02,
    NUM_3 = 0x03,
    NUM_4 = 0x04,
    NUM_5 = 0x05,
    NUM_6 = 0x06,
    NUM_7 = 0x07,
    NUM_8 = 0x08,
    NUM_9 = 0x09,
    MINUS = 0x0A, //-号
    LETTER_E = 0x0B,
    LETTER_H = 0x0C,
    LETTER_L = 0x0D,
    LETTER_P = 0x0E,
    BLANK = 0x0F,  //无显示
    LETTER_AR = 0x10 //=16 =SYMBOLS  AorR
} MAX7219_Numeric;

void max7219_Init(uint8_t intensivity);
void max7219_SetIntensivity(uint8_t intensivity);
void max7219_Clean(void);
/*void max7219_SendData(uint8_t addr, uint8_t data);*/
void max7219_Turn_On(void);
void max7219_Turn_Off(void);
void max7219_Decode_On(void);
void max7219_Decode_Off(void);
void max7219_PrintDigit(MAX7219_Digits position, MAX7219_Numeric numeric, bool point);
MAX7219_Digits max7219_PrintItos(MAX7219_Digits position, int value);
MAX7219_Digits max7219_PrintNtos(MAX7219_Digits position, uint32_t value, uint8_t n);
MAX7219_Digits max7219_PrintFtos(MAX7219_Digits position, float value, uint8_t n);

int LED8Main(void);

static uint8_t decodeMode = 0x00;

static uint8_t SYMBOLS[] = {
    0x7E, // numeric 0
    0x30, // numeric 1
    0x6D, // numeric 2
    0x79, // numeric 3
    0x33, // numeric 4
    0x5B, // numeric 5
    0x5F, // numeric 6
    0x70, // numeric 7
    0x7F, // numeric 8
    0x7B, // numeric 9
    0x01, // minus
    0x4F, // letter E
    0x37, // letter H
    0x0E, // letter L
    0x67, // letter P
    0x00, // blank
    0x77  //AorR
};

static uint16_t getSymbol(uint8_t number);
static uint32_t lcdPow10(uint8_t n);

/*8 DIGITS func end*/
void max7219_Init(uint8_t intensivity)
{
    max7219_Turn_On();
    max7219_SendData(REG_SCAN_LIMIT, NUMBER_OF_DIGITS - 1);
    max7219_SetIntensivity(intensivity);
    max7219_Clean();
}
//显示亮度
void max7219_SetIntensivity(uint8_t intensivity)
{
    if (intensivity > 0x0F)
    {
        return;
    }

    max7219_SendData(REG_INTENSITY, intensivity);
}

void max7219_Clean()
{
    uint8_t clear = 0x00;

    if (decodeMode == 0xFF)
    {
        clear = BLANK;
    }

    for (int i = 0; i < 8; ++i)
    {
        max7219_SendData(i + 1, clear);
    }
}

// #define data_len (20*1024)
#define data_len (20 * 1024)
uint8_t tx_data[data_len] = {0};

inline void max7219_SendData(uint8_t addr, uint8_t data)
{
    HAL_Status ret = HAL_OK;
    HAL_SPI_CS(DEMO_SPI_PORT, 1);
    // printf("spi write...\n");
    tx_data[0] = addr;
    tx_data[1] = data;
    ret = HAL_SPI_Transmit(DEMO_SPI_PORT, &tx_data, 2);
    if (ret != HAL_OK)
    {
        printf("spi 1write failed");
    }

    HAL_SPI_CS(DEMO_SPI_PORT, 0);
}
//操作方式
void max7219_Turn_On(void)
{
    max7219_SendData(REG_SHUTDOWN, 0x01);
}
//操作方式
void max7219_Turn_Off(void)
{
    max7219_SendData(REG_SHUTDOWN, 0x00);
}
//译码方式
void max7219_Decode_On(void)
{
    decodeMode = 0xFF;
    max7219_SendData(REG_DECODE_MODE, decodeMode);
}
//译码方式
void max7219_Decode_Off(void)
{
    decodeMode = 0x00;
    max7219_SendData(REG_DECODE_MODE, decodeMode);
}

void max7219_PrintDigit(MAX7219_Digits position, MAX7219_Numeric numeric, bool point)
{
    if (position > NUMBER_OF_DIGITS)
    {
        return;
    }

    if (point)
    {
        if (decodeMode == 0x00)
        {
            max7219_SendData(position, getSymbol(numeric) | (1 << 7));
        }
        else if (decodeMode == 0xFF)
        {
            max7219_SendData(position, numeric | (1 << 7));
        }
    }
    else
    {
        if (decodeMode == 0x00)
        {
            max7219_SendData(position, getSymbol(numeric) & (~(1 << 7)));
        }
        else if (decodeMode == 0xFF)
        {
            max7219_SendData(position, numeric & (~(1 << 7)));
        }
    }
}

MAX7219_Digits max7219_PrintItos(MAX7219_Digits position, int value)
{
    max7219_SendData(REG_DECODE_MODE, 0xFF);

    int32_t i;

    if (value < 0)
    {
        if (position > 0)
        {
            max7219_SendData(position, MINUS);
            position--;
        }
        value = -value;
    }

    i = 1;

    while ((value / i) > 9)
    {
        i *= 10;
    }

    if (position > 0)
    {
        max7219_SendData(position, value / i);
        position--;
    }

    i /= 10;

    while (i > 0)
    {
        if (position > 0)
        {
            max7219_SendData(position, (value % (i * 10)) / i);
            position--;
        }

        i /= 10;
    }

    max7219_SendData(REG_DECODE_MODE, decodeMode);

    return position;
}

MAX7219_Digits max7219_PrintNtos(MAX7219_Digits position, uint32_t value, uint8_t n)
{
    max7219_SendData(REG_DECODE_MODE, 0xFF);

    if (n > 0u)
    {
        uint32_t i = lcdPow10(n - 1u);

        while (i > 0u) /* Display at least one symbol */
        {
            if (position > 0u)
            {
                max7219_SendData(position, (value / i) % 10u);
                position--;
            }

            i /= 10u;
        }
    }

    max7219_SendData(REG_DECODE_MODE, decodeMode);

    return position;
}

MAX7219_Digits max7219_PrintFtos(MAX7219_Digits position, float value, uint8_t n)
{
    if (n > 4)
    {
        n = 4;
    }

    max7219_SendData(REG_DECODE_MODE, 0xFF);

    if (value < 0.0)
    {
        if (position > 0)
        {
            max7219_SendData(position, MINUS);
            position--;
        }

        value = -value;
    }

    position = max7219_PrintItos(position, (int32_t)value);

    if (n > 0u)
    {
        max7219_PrintDigit(position + 1, ((int32_t)value) % 10, true);

        position = max7219_PrintNtos(position, (uint32_t)(value * (float)lcdPow10(n)), n);
    }

    max7219_SendData(REG_DECODE_MODE, decodeMode);

    return position;
}

static uint16_t getSymbol(uint8_t number)
{
    return SYMBOLS[number];
}

static uint32_t lcdPow10(uint8_t n)
{
    uint32_t retval = 1u;

    while (n > 0u)
    {
        retval *= 10u;
        n--;
    }

    return retval;
}
/*8 DIGITS func end*/

static int wifi_device_connect()
{
    const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID;
    const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK;

    if (WIFI_SUCCESS != EnableWifi())
    {
        printf("Error: EnableWifi fail.\n");
        return;
    }
    printf("EnableWifi Success.\n");

    if (WIFI_STA_ACTIVE == IsWifiActive())
        printf("Wifi is active.\n");

    OS_Sleep(1);

    if (WIFI_SUCCESS != Scan())
    {
        printf("Error: Scan fail.\n");
        return;
    }
    printf("Wifi Scan Success.\n");

    OS_Sleep(1);

    WifiScanInfo scan_results[30];
    unsigned int scan_num = 30;

    if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num))
    {
        printf("Error: GetScanInfoList fail.\n");
        return;
    }

    WifiDeviceConfig config = {0};
    int netId = 0;

    int i;
    for (i = 0; i < scan_num; i++)
    {
        if (0 == strcmp(scan_results[i].ssid, ssid_want_connect))
        {
            memcpy(config.ssid, scan_results[i].ssid,
                   WIFI_MAX_SSID_LEN);
            memcpy(config.bssid, scan_results[i].bssid,
                   WIFI_MAC_LEN);
            strcpy(config.preSharedKey, psk);
            config.securityType = scan_results[i].securityType;
            config.wapiPskType = WIFI_PSK_TYPE_ASCII;
            config.freq = scan_results[i].frequency;
            break;
        }
    }

    if (i >= scan_num)
    {
        printf("Error: No found ssid in scan_results\n");
        return;
    }
    printf("GetScanInfoList Success.\n");

    if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId))
    {
        printf("Error: AddDeviceConfig Fail\n");
        return;
    }
    printf("AddDeviceConfig Success.\n");

    if (WIFI_SUCCESS != ConnectTo(netId))
    {
        printf("Error: ConnectTo Fail\n");
        return;
    }
    printf("ConnectTo Success\n");
}

static int my_sntp_init()
{
    if (sntp_set_server(0, "0.cn.pool.ntp.org") == 0)
    {
        printf("set OK \r\n");
    }
}
int LED8Main(void)
{
    printf("platform_init.\n");
    /*platform_init();*/
    printf("spi demo started.\n");

    SPI_Global_Config spi_param;

    spi_param.cs_level = DEMO_SPI_CS_LEVEL;
    spi_param.mclk = DEMO_SPI_MCLK;

    HAL_SPI_Init(DEMO_SPI_PORT, &spi_param);

    SPI_Config spi_Config;
    HAL_Status ret = HAL_OK;
    uint8_t cmd = DEMO_FLASH_INSTRUCTION_RDID; /* read flash id cmd */
    uint32_t data = 0;

    spi_Config.firstBit = SPI_TCTRL_FBS_MSB; //
    //SPI_LITTLEENDIAN;//第一字节 SPI_LITTLEENDIAN,SPI_BIGENDIAN
    spi_Config.mode = SPI_CTRL_MODE_MASTER;
    //SPI_MODE_MASTER;//SPI_MODE_SLAVE 从,SPI_MODE_MASTER 主
    spi_Config.opMode = SPI_OPERATION_MODE_POLL;
    spi_Config.sclk = 24000000;
    spi_Config.sclkMode = SPI_SCLK_Mode0;

    printf("spi open...\n");
    ret = HAL_SPI_Open(DEMO_SPI_PORT, DEMO_SPI_CS, &spi_Config, 5000);
    if (ret != HAL_OK)
    {
        printf("spi open failed");
        return ret;
    }

    HAL_SPI_Config(DEMO_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_NORMAL);

    printf("spi demo over.\n");
    return 0;
}

//抄  https://github.com/taburyak/STM32_MAX7219_SPI
//demos https://stm32withoutfear.blogspot.com/2019/06/stm32-7segments-8digits-max7219-spi.html

static void MainThread(void *arg)
{
    printf("MainThread.\n");
    LED8Main();
    max7219_Init(7);
    max7219_SetIntensivity(1);
    max7219_Decode_Off();
                max7219_SendData(DIGIT_4,79);
                max7219_SendData(DIGIT_3, 119);
                max7219_SendData(DIGIT_2, 119);
    LOS_Msleep(5000);            
    max7219_Decode_On();
    max7219_PrintNtos(DIGIT_8,88888888, 8); //此处前面带 0 补充4位
    LOS_Msleep(1000);
    max7219_Clean();
    int modi;
    int setint = 1;
    while (1)
    {
        modi++;
        setint++;
        if (setint == 16)
        {
            setint = 1;
        }
        max7219_SetIntensivity(setint);

        if (WIFI_STA_ACTIVE == IsWifiActive())
        {
            // max7219_Clean();
            printf("Wifi is active.\n");
            if (sntp_request(NULL) != 0)
            {
                //视频中用手捂住开发板后会进入此处
                /*max7219_PrintDigit(DIGIT_4, LETTER_E, false);*/
                LOS_Msleep(1);
                max7219_Decode_Off();
                max7219_Clean();
                LOS_Msleep(1);
                max7219_PrintDigit(DIGIT_6, LETTER_AR,false);//A OR R
                max7219_SendData(DIGIT_4,79);//E
                max7219_SendData(DIGIT_3, 119);//R
                max7219_SendData(DIGIT_2, 119);//R
                LOS_Msleep(5000);
                max7219_Decode_On();
                max7219_Clean();
                printf("<sntp> <response : fail>\n");
                // goto bexit;
            }
            else
            {
                // max7219_Clean();
                sntp_time *time = (sntp_time *)sntp_obtain_time();
                printf("<sntp><response:success>\n");
                //11111111
                if (modi % 2 == 0)
                {
                    max7219_PrintNtos(DIGIT_8, time->year + SNTP_YEAR_OFFSET, 4);//年
                    max7219_PrintNtos(DIGIT_4, time->mon, 2);                      //月
                    max7219_PrintNtos(DIGIT_2, time->day, 2);                      //日
                }
                else
                {
                    max7219_PrintNtos(DIGIT_8, time->hour, 2);//小时     第一位无数字自动补充0
                    max7219_PrintDigit(DIGIT_6, BLANK, true);// 。
                    max7219_PrintNtos(DIGIT_5, time->min, 2);//分        第一位无数字自动补充0
                    max7219_PrintDigit(DIGIT_3, BLANK, true);// 。
                    max7219_PrintNtos(DIGIT_2, time->sec & 0x3f, 2);//秒 第一位无数字自动补充0 
                }
                CMD_LOG(1, "sntp(%u-%02u-%02u ", time->year + SNTP_YEAR_OFFSET, time->mon, time->day);
                CMD_LOG(1, "%02u:%02u:%02u)\n", time->hour, time->min, time->sec);
                LOS_Msleep(4000);
            }
        }
        else
        {   //初始化连接 wifi
            max7219_Clean();
            max7219_PrintDigit(DIGIT_8, BLANK, true);
            LOS_Msleep(1000);
            max7219_PrintDigit(DIGIT_7, BLANK, true);
            LOS_Msleep(1000);
            max7219_PrintDigit(DIGIT_6, BLANK, true);
            LOS_Msleep(1000);
            max7219_PrintDigit(DIGIT_5, BLANK, true);
            printf("Wifi is passive.\n");
            wifi_device_connect();
            max7219_PrintDigit(DIGIT_4, BLANK, true);
            LOS_Msleep(1000);
            max7219_PrintDigit(DIGIT_3, BLANK, true);
            LOS_Msleep(1000);
            max7219_PrintDigit(DIGIT_2, BLANK, true);
            LOS_Msleep(1000);
            max7219_PrintDigit(DIGIT_1, BLANK, true);
            LOS_Msleep(1000);
        }
    }
    printf("bexit is passive.\n");
}

void SNTPTestMain(void) //(2)
{
    printf("SNTP Test Start\n");
    if (OS_ThreadIsValid(&g_main_thread))
    {
        printf("sntp task is running\n");
    }
    else
    {
        if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
                            OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
        {
            printf("[ERR] Create SNTP Test  MainThread Failed\n");
        }
    }
}

SYS_RUN(SNTPTestMain);

//必须以app开头 否则不会调用

ctrl+o 保存

   回车

ctrl+x 退出

对上面操作完毕后
由于我们修改了/home/make/xr806_openharmony/device/xradio/xr806/ohosdemo/BUILD.gn
cd /home/make/xr806_openharmony
hb build -f
必须-f 如若未修改BUILD.gn 大可不必 直接 hb build 即可

IMG_20211223_232851_HDR.jpg
IMG_20211223_232850_HDR.jpg

IMG_20211223_232457_HDR.jpg
IMG_20211223_232455_HDR.jpg

推荐阅读
关注数
3
内容数
1
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息