前言
感芯科技推出了一款64线程的MCU,此前在感芯科技的公众号申请了一块收费的开发板,进行了简略的评测应用,整体上应用体验良好。首先这款开发板的个性是64线程,高实时和高确定性,其线程频率由外部时钟动态片分,换言之就是线程逻辑上独立,实用于高实时的利用场景——它就是MC3172
。
根底信息
这块开发板目前曾经调试过PWM呼吸灯,UART,SPI,OLED亮屏等性能,整体上手难度个别,开发板图例如下,更多相干信息请返回文章底部进入开发板官网链接进行查看:
点亮OLED
本次例程针对SH1106,这块OLED采纳SPI协定,屏幕大小为1.3英寸,分辨率为128 * 64。
话不多说,间接上代码:
/* LED 128*64 7 PINs SPI Protocal Driver * @Date 2022-07-16 * @Author Winter * @License Apache Licence 2.0 */#include "MC3172.h"#define OLED_COLUMN_NUMBER 128 // Screen resolution width#define OLED_ROW_NUMBER 64 // Screen resolution height#define OLED_COLUMN_OFFSET 2#define OLED_PAGE_NUMBER OLED_ROW_NUMBER / 8 // how many pages to divide ROW#define OLED_POS_PORT GPIOC_BASE_ADDR#define OLED_GPCOM_PORT GPCOM9_BASE_ADDR#define OLED_GPCOM_TX_RP GPCOM9_TX_RP#define OLED_GPCOM_TX_WP GPCOM9_TX_WPstatic u8 video_buffer[1024]; // Video Memory// RST(RES): Reset Signal Input, High for normal operation// Position: PORTC[2]#define SET_SPI_RST_0 GPIO_SET_OUTPUT_PIN_TO_0(OLED_POS_PORT, (GPIO_PIN2))#define SET_SPI_RST_1 GPIO_SET_OUTPUT_PIN_TO_1(OLED_POS_PORT, (GPIO_PIN2))// DC: Data/Command Control// Position: PORTC[5]#define SET_SPI_DC_0 GPIO_SET_OUTPUT_PIN_TO_0(OLED_POS_PORT, (GPIO_PIN5))#define SET_SPI_DC_1 GPIO_SET_OUTPUT_PIN_TO_1(OLED_POS_PORT, (GPIO_PIN5))// CS: Chip Select// Position: PORTC[4]#define SET_SPI_CS_0 GPIO_SET_OUTPUT_PIN_TO_0(OLED_POS_PORT, (GPIO_PIN4))#define SET_SPI_CS_1 GPIO_SET_OUTPUT_PIN_TO_1(OLED_POS_PORT, (GPIO_PIN4))// SH1106 commands for SPIconst unsigned char _init_cmd[25] = { 0xAE, //Set display off 0xD5, //Set frequency division 0x80, //[3:0],Set display divide ratio;[7:4],(OSC drequency) 0xA8, //Set multiplex ratio. 0X3F, //default is 1/64 0xD3, //Set display offset 0X00, //default is 0 0x40, //set display start line [5:0] 0x8D, //Set charge pump 0x14, 0x20, //Set address mode 0x02, //[1:0],00,column first;01,row first;10,page first;default is 10; 0xA1, //Set segment Re-map,bit0:0,0->0;1,0->127; 0xC8, //Set COM output scan direction,bit3:0,normal mode;1,redefine mode COM[N-1]->COM0;N:driver channeles (C0 display inverse) C8 0xDA, //Set COM I/O 0x12, //[5:4] 0x81, // Set contrast 0x66, // Set brightness, 1~255;default is 0X7F 0xD9, //Set pre-charge period 0xf1, //[3:0],PHASE 1;[7:4],PHASE 2; 0xDB, //Set VCOMH deselect level 0x30, //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; 0xA4, //Set entire display on/off ;bit0:1,on;0,off; 0xA6, //Set display mode;bit0:1,Normal;0,Inverse 0xAF, //Set display on};void _oled_init_io(void){ // CS:PORTC[4] DC:PORTC[5] RES:PORTC[2] SDA:PORTC[6] SCK:PORTC[7] INTDEV_SET_CLK_RST(OLED_POS_PORT, (INTDEV_RUN | INTDEV_IS_GROUP0 | INTDEV_CLK_IS_CORECLK_DIV32)); // 133/32 GPIO_SET_OUTPUT_EN_VALUE(OLED_POS_PORT, (GPIO_PIN2 | GPIO_PIN3 | GPIO_PIN4 | GPIO_PIN5), GPIO_SET_ENABLE); INTDEV_SET_CLK_RST(OLED_GPCOM_PORT, (INTDEV_RUN | INTDEV_IS_GROUP0 | INTDEV_CLK_IS_CORECLK_DIV32)); GPCOM_SET_OUT_PORT(OLED_GPCOM_PORT, (GPCOM_P0_OUTPUT_DISABLE | GPCOM_P1_OUTPUT_DISABLE | GPCOM_P2_OUTPUT_ENABLE | GPCOM_P2_IS_MASTER_OUT | GPCOM_P3_OUTPUT_ENABLE | GPCOM_P3_IS_MASTER_CLK)); GPCOM_SET_COM_MODE(OLED_GPCOM_PORT, (GPCOM_SPI_MASTER_MODE0 | GPCOM_TX_MSB_FIRST | GPCOM_RX_MSB_FIRST)); GPCOM_SET_COM_SPEED(OLED_GPCOM_PORT, 4156250, 1000000); GPCOM_SET_OVERRIDE_GPIO(OLED_GPCOM_PORT, (GPCOM_P2_OVERRIDE_GPIO | GPCOM_P3_OVERRIDE_GPIO));}void _oled_send_byte(unsigned char byte){ u8 tx_data_wp = 0; tx_data_wp = GPCOM_GET_TX_WP(OLED_GPCOM_PORT); GPCOM_SEND_TX_DATA(OLED_GPCOM_PORT, tx_data_wp + 0, byte); // Write data to cache 0 buffer. tx_data_wp += 1; GPCOM_SEND_TX_WP(OLED_GPCOM_PORT, tx_data_wp); while (OLED_GPCOM_TX_RP != OLED_GPCOM_TX_WP) { // waiting for transmission };} // SPI_SendBytevoid _oled_send_cmd(unsigned char o_command){ SET_SPI_DC_0; SET_SPI_CS_0; _oled_send_byte(o_command); SET_SPI_CS_1; // SPI_DC_1;}void _oled_send_data(unsigned char o_data){ SET_SPI_DC_1; SET_SPI_CS_0; _oled_send_byte(o_data); SET_SPI_CS_1;}void _oled_set_column(unsigned char column){ column += OLED_COLUMN_OFFSET; _oled_send_cmd(0x10 | (column >> 4)); //Setting the column higher bits. _oled_send_cmd(0x00 | (column & 0x0F)); //Setting the column lower bits.}void _oled_set_page(unsigned char page){ _oled_send_cmd(0xb0 + page);}void _oled_clear(void){ unsigned char page, column; for (page = 0; page < OLED_PAGE_NUMBER; page++) // page loop { _oled_set_page(page); _oled_set_column(0); for (column = 0; column < OLED_COLUMN_NUMBER; column++) // column loop { _oled_send_data(0x00); } }}void _oled_fullfilled(void){ unsigned char page, column; for (page = 0; page < OLED_PAGE_NUMBER; page++) // page loop { _oled_set_page(page); _oled_set_column(0); for (column = 0; column < OLED_COLUMN_NUMBER; column++) // column loop { _oled_send_data(0xff); } }}void _oled_init_cmds(void){ unsigned char i; for (i = 0; i < 25; i++) { _oled_send_cmd(_init_cmd[i]); }}void _frame_refresh(const unsigned char *ptr_pic){ unsigned char page, column; for (page = 0; page < (OLED_ROW_NUMBER / 8); page++) // page loop { _oled_set_page(page); _oled_set_column(0); for (column = 0; column < OLED_COLUMN_NUMBER; column++) // column loop { _oled_send_data(*ptr_pic++); } }}void _frame_refresh_inverse(const unsigned char *ptr_pic){ unsigned char page, column, data; for (page = 0; page < (OLED_ROW_NUMBER / 8); page++) // page loop { _oled_set_page(page); _oled_set_column(0); for (column = 0; column < OLED_COLUMN_NUMBER; column++) // column loop { data = *ptr_pic++; data = ~data; _oled_send_data(data); } }}int oled_init(void){ _oled_init_io(); SET_SPI_RST_0; delay_ms(500); SET_SPI_RST_1; delay_ms(500); _oled_init_cmds(); _oled_fullfilled(); delay_ms(500); _oled_clear();}void oled_refresh(){ _frame_refresh(&video_buffer[0]);}// Inverse the bit value for each pixel.void oled_refresh_inverse(){ _frame_refresh_inverse(&video_buffer[0]);}
在以上的代码中video_buffer
为屏幕展现的内容,在此处提供一个内容帧用于验证参考:
//replace vide_buffer with below:static u8 video_buffer[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,8,56,248,96,0,0,0,0,0,0,0,0,0,0,128,128,192,64,64,64,96,32,32,32,32,96,64,64,64,192,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,64,32,48,16,8,12,4,4,6,6,2,2,2,2,2,2,2,4,4,4,4,4,12,8,12,15,11,8,8,8,8,8,12,4,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,2,6,4,12,16,48,96,192,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,14,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,224,240,224,0,0,0,0,0,0,0,0,0,128,96,32,0,0,0,0,0,0,192,128,224,76,246,112,244,200,200,240,240,112,144,32,0,0,0,0,0,1,6,56,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,224,32,32,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,15,15,0,0,0,0,0,0,224,28,3,0,0,0,0,192,224,48,250,63,239,247,187,217,239,255,123,28,7,11,1,2,0,0,0,0,0,0,0,0,0,224,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,255,176,240,255,240,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,96,30,3,0,0,0,0,0,1,6,8,24,48,32,33,33,99,67,67,67,67,131,131,129,128,128,128,128,64,64,64,64,96,32,32,32,48,24,12,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,7,6,3,6,12,8,8,24,16,48,32,32,32,96,64,64,64,64,64,64,192,128,192,192,96,96,80,88,68,70,65,65,64,64,64,64,64,192,128,0,0,0,0,0,0,192,32,24,4,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,224,240,172,131,160,192,128,192,192,254,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,48,24,8,12,14,1,0,0,0,0,0,0,0,0,7,62,112,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
在代码中嵌入该帧内容,运行后你将会取得一个外星人版本的史努比!!!
扩大
笔者在以上根底上进行了扩大,实现了随画随显性能,成果如下图,有趣味应用该开发板的网友能够尝试更多有意思的创意和体验。
结语
支付开发板至今大略有一个月工夫,笔者在工作之余去体验了该开发板,最大的体验是多线程的无感调度(硬件实现),应用该个性能够实现更多须要高独立性高实时性的利用,一起期待更多有意思的创意吧!
更多内容相干
官网代码仓库:gxchip (gitee.com),官网:感芯科技