【XR806开发板试用】spi+ntp+max7219=实时时钟
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 即可