<STM32G431测试>一、开箱GPIO测试 快递收到后立即开箱,与STM一贯的作风精简的塑料盒子包装的小开发板,支持Arduino的插座,和引出芯片引脚的双排2.54插针。见照片1-1。 首先想起的是测试GPIO,常规点亮LED,板子来时就有1个LED闪烁,就直接想用驱显LCD进行试验。 ; l; H8 e, H! B$ E! Q网上搜到STM32G431RB-NUCLEO的实例2个: G4PMSM24V200W1024NENC - L. b6 A5 ^, L3 D0 a- l# o: `/ qSTM32Cube_FW_G4_V1.0.0 前者按照芯片功能逐一实验,后者好像采用RTOS实现的功能,本试验先采用前者,之后在测试前者。 4 F* _5 D. `& }: P9 N+ `. |2 x* _0 L/ I实验平台:Windows 7 64位旗舰版,开发平台Keil5.23/25,工程STM32Cube_FW_G4_V1.0.0。 查看Nucleo引脚图和main.h文档,GPIO的A口 0,2~4,7~11,13~15已被占用,B口 0,1,8占用,C口 0,1,4,5,13占用,驱显采用B或C口,距离较近的B12,13,14,15正好用于6线串口屏,手中这类屏较多,0713,6903,12864,OLED等一堆,顺手拿了6903这款日本早年出的lcd,改造后带背光,3V3下电流1mA不到。 打开main.c文档static void MX_GPIO_Init(void)函数,可以知道 6 ^/ V8 e4 w3 v9 AABCF的IO口时钟已打开 __HAL_RCC_GPIOC_CLK_ENABLE(); / \/ i0 ^) D, F% k$ s __HAL_RCC_GPIOF_CLK_ENABLE(); - N4 ]" w* D1 P4 g& J9 f* P* r __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); 参照/*ConfigureGPIO pin : Start_Stop_Pin */口的定义将LCD的4根数据蔻斯能够以如下: - r% ~2 @" [2 T ?! K0 U L K//LCD PIN GPIO_InitStruct.Pin = LCDRES;//,LCDREG,LCDCLK,LCDDIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; / N+ l( W7 Z1 O& T6 ~/ g9 d" h GPIO_InitStruct.Pull = GPIO_NOPULL; 4 ~& v- q0 k0 ~, P HAL_GPIO_Init(LCDPORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = LCDREG; % p3 N. v) J# F9 a GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(LCDPORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = LCDCLK; / I! D0 J4 |1 q' H4 H! l3 J2 U GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; ( u( k5 ?% x& b, F4 _) E1 J- H GPIO_InitStruct.Pull = GPIO_NOPULL; $ m5 f' |! n5 f% S4 ^4 N7 u& D HAL_GPIO_Init(LCDPORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = LCDDIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; 4 t% Q0 i. s" J2 G HAL_GPIO_Init(LCDPORT, &GPIO_InitStruct); ; k: C/ P: j8 D7 @/ ~* l添加到此函数中。 在main.h函数中增加定义: ! P/ @& W$ V" v, i! ~5 V#define LCDRES GPIO_PIN_12 #define LCDDIN GPIO_PIN_13 3 q3 X( d x {% \#define LCDREG GPIO_PIN_14 #define LCDCLK GPIO_PIN_15 6 b: F4 y2 I/ f! O) Y" \#define LCDPORT GPIOB 以下是6903.h函数代码: ; ~9 g' S% A3 R; r, C. B& [3 }! mextern int k; //6903 102X64LCD const unsigned char asc2[][6]={//8x6 Dots0-40 ( B1 R/ J( ]3 \$ N{0x00,0x3E,0x45,0x49,0x51,0x3E},//0 , x. X% ^+ F$ V{0x00,0x00,0x21,0x7F,0x01,0x00},//1 {0x00,0x31,0x43,0x45,0x49,0x31},//2 {0x00,0x22,0x49,0x49,0x49,0x36},//3 : l3 }6 P5 S* e% [# x6 m{0x00,0x04,0x0C,0x14,0x7F,0x04},//4 7 [. v) J# L4 n{0x00,0x72,0x51,0x51,0x51,0x4E},//5-5 {0x00,0x3E,0x49,0x49,0x49,0x06},//6 + R, i5 m- O- ?5 C{0x00,0x40,0x43,0x4C,0x50,0x60},//7 {0x00,0x36,0x49,0x49,0x49,0x36},//8 3 ]- R# S; u- ], X{0x00,0x30,0x48,0x48,0x48,0x3F},//9 , e# B& b1 h5 F- N$ B{0x00,0x1F,0x24,0x64,0x24,0x1F},//A-10 {0x00,0x41,0x7F,0x49,0x49,0x36},//B 6 l4 o6 r5 ~8 K4 v{0x00,0x3E,0x41,0x41,0x41,0x22},//C 4 ^0 Q2 i- X3 p, `8 U1 h{0x00,0x41,0x7F,0x41,0x41,0x3E},//D 0 C: e5 H7 l0 I3 ^4 M{0x00,0x41,0x7F,0x49,0x49,0x63},//E ( u5 n/ O6 H7 ?/ o" |{0x00,0x41,0x7F,0x49,0x5C,0x60},//F-15 $ D/ ] B. ]5 b$ V0 P" f. F" a{0x00,0x3E,0x41,0x45,0x47,0x24},//G , ?' }8 p. a7 c9 V& T: G{0x41,0x7F,0x08,0x08,0x08,0x7F},//H {0x00,0x00,0x41,0x7F,0x41,0x00},//I # E% `5 J' _4 f, w0 E{0x00,0x42,0x41,0x7F,0x40,0x40},//J {0x00,0x41,0x7F,0x59,0x24,0x43},//K-20 {0x00,0x40,0x7F,0x41,0x01,0x03},//L % h5 v6 W3 n1 f& H6 ^7 v{0x00,0x7F,0x20,0x1E,0x20,0x7F},//M {0x00,0x7F,0x30,0x18,0x06,0x7F},//N {0x00,0x3E,0x41,0x41,0x41,0x3E},//O {0x00,0x41,0x7F,0x49,0x48,0x30},//P-25 9 m2 R; S/ \4 t5 `1 n{0x00,0x3E,0x41,0x47,0x42,0x3D},//Q 8 @8 H4 m) u: f$ `2 ~{0x00,0x41,0x7F,0x49,0x4C,0x33},//R {0x00,0x32,0x49,0x49,0x49,0x26},//S {0x00,0x60,0x41,0x7F,0x41,0x60},//T 7 L. w6 ^0 L+ V0 M3 Q{0x00,0x7E,0x01,0x01,0x01,0x7E},//U-30 {0x00,0x7C,0x02,0x01,0x02,0x7C},//V ! e* s3 p( O$ w, u0 N$ m{0x00,0x7C,0x03,0x3C,0x03,0x7C},//W {0x00,0x43,0x24,0x18,0x24,0x43},//X {0x00,0x60,0x18,0x07,0x18,0x60},//Y 5 k( d# g; V, y ~{0x00,0x63,0x45,0x49,0x51,0x63},//Z-35 - a) n0 z- c+ S' a1 w! g{0x00,0x00,0x00,0x01,0x00,0x00},//. {0x00,0x14,0x14,0x14,0x14,0x14},//= {0x00,0x08,0x08,0x3E,0x08,0x08},//+ {0x00,0x08,0x08,0x08,0x08,0x08},//- $ [$ D: k! e7 `( G{0x00,0x00,0x00,0x24,0x00,0x00},//:-40 }; & H. B/ z) a- c4 O$ p4 oconst unsigned char hanzi[][12]={//--16X12 汉字点阵码 {0x44,0x44,0x7F,0x44,0x08,0x48,0x4F,0x48,0x4F,0x48,0x08,0x00},//玩 j7 [- f' c. ]8 t{0x20,0x20,0xC0,0x40,0x10,0x60,0x80,0x00,0xE0,0x10,0x70,0x00}, ' @" N6 z0 T6 `- l{0x00,0xFF,0x84,0xA4,0xA7,0xA4,0xA7,0xA4,0x84,0x80,0xFF,0x00},//园 {0x00,0xF0,0x50,0x90,0x10,0x10,0x90,0x50,0xD0,0x10,0xF0,0x00}, ) c, R3 Z( I4 r* g2 D{0x08,0x08,0xFF,0x08,0x04,0x3F,0x08,0xFF,0x10,0x21,0x3F,0x00},//地 ; Q. f! L8 Q# _' S7 S3 w/ r{0x20,0x20,0xC0,0x40,0x00,0xE0,0x10,0x90,0x10,0x10,0x70,0x00}, {0x00,0x3E,0xAA,0x6A,0x2A,0x3F,0x2A,0x6A,0xAA,0x3E,0x00,0x00},//单 4 \( p- L- j# _* w{0x80,0x80,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x80,0x00}, + ^0 `) {, c$ n! }* |, y+ l{0x00,0x00,0x7F,0x09,0x09,0x09,0x09,0xF9,0x09,0x08,0x08,0x00},//片 {0x10,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00}, : [' `) Q0 O( s5 p1 S9 g9 C{0x11,0x16,0xFF,0x14,0x02,0x7F,0x40,0x40,0x7F,0x00,0x00,0x00},//机 {0x00,0x00,0xF0,0x10,0x20,0xC0,0x00,0x00,0xE0,0x10,0x70,0x00}, {0x3F,0x24,0x24,0x24,0xFF,0x24,0x24,0x24,0x3F,0x00,0x00,0x00},//电 {0xC0,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x10,0x70,0x00}, {0x00,0x7F,0x40,0x42,0x42,0x42,0x5F,0x42,0x42,0x42,0x40,0x00},//压 1 T, }! i8 c9 s$ I{0x10,0xE0,0x10,0x10,0x10,0x10,0xF0,0x10,0x90,0x50,0x10,0x00}, + t7 C. o$ b/ n3 ^ v{0x44,0x22,0x00,0x24,0x2D,0x34,0xA5,0x64,0x25,0x2C,0x26,0x00},//流 7 \/ H, A, @4 S' O1 y' k* c{0x20,0x40,0x10,0x20,0xC0,0x00,0xF0,0x00,0xE0,0x10,0x70,0x00}, ; ~5 \. G$ O" l5 _: g' }7 u, |{0x88,0x4F,0x00,0x5E,0x52,0x53,0xFF,0x53,0x52,0x5E,0x40,0x00},//速 5 ]9 [6 B/ a% f5 ]! I{0x10,0xE0,0x10,0x50,0x90,0x10,0xF0,0x10,0x90,0x50,0x10,0x00}, {0x00,0x7F,0x50,0x51,0x7D,0x55,0xD5,0x55,0x7D,0x51,0x50,0x00},//度 5 ?& J9 [3 j. m+ z" G( k; z{0x10,0xE0,0x00,0x10,0x90,0x50,0x20,0x20,0x50,0x90,0x10,0x00}, {0x00,0x79,0x48,0x4F,0x79,0x00,0x7F,0x48,0x48,0x48,0x4F,0x00},//距 {0x10,0xF0,0x10,0xE0,0x20,0x00,0xF0,0x90,0x90,0x90,0x90,0x00}, {0x41,0x5D,0x45,0x6D,0x55,0xD7,0x55,0x6D,0x45,0x5D,0x41,0x00},//离 {0xF0,0x00,0x20,0x60,0xA0,0x20,0x60,0x30,0x00,0x10,0xF0,0x00}, {0x10,0x2F,0xCA,0x4A,0x4A,0x4F,0x5A,0x6A,0x0A,0x0F,0x00,0x00},//角 {0x10,0xE0,0x80,0x80,0x80,0xE0,0x80,0x80,0x90,0xF0,0x00,0x00}, {0x20,0x26,0x2A,0x32,0xE2,0x2F,0x22,0x22,0x22,0x22,0x20,0x00},//东 {0x20,0x40,0x80,0x00,0x10,0xF0,0x00,0x00,0x80,0x40,0x20,0x00}, {0x80,0x9F,0x90,0x91,0xFE,0x90,0xFE,0x91,0x91,0x9F,0x80,0x00},//西 {0x00,0xF0,0xA0,0x20,0x20,0x20,0x20,0x20,0x20,0xF0,0x00,0x00}, {0x40,0x5F,0x50,0x5A,0x56,0xF3,0x56,0x5A,0x50,0x5F,0x40,0x00},//南 3 T5 T( B! i) P# w. N A{0x00,0xF0,0x80,0x80,0x80,0xE0,0x80,0x90,0x90,0xF0,0x00,0x00}, {0x08,0x08,0x08,0xFF,0x00,0x00,0xFF,0x04,0x08,0x10,0x20,0x00},//北 {0x40,0x40,0x80,0xF0,0x00,0x00,0xE0,0x10,0x10,0x10,0x70,0x00}, {0x08,0x48,0x28,0x19,0x0A,0xFF,0x0A,0x19,0x28,0x48,0x08,0x00},//米 {0x40,0x40,0x80,0x00,0x00,0xF0,0x00,0x00,0x80,0x40,0x40,0x00}, ) n# o! [& J( i6 u+ r1 J {* Y{0x00,0x7F,0x40,0x5F,0x55,0x55,0x5F,0x55,0x55,0x5F,0x40,0x00},//厘 ~* d! J9 L8 g{0x10,0xE0,0x10,0x50,0x50,0x50,0xF0,0x50,0x50,0x50,0x10,0x00}, {0x46,0x44,0x5D,0x55,0x55,0xD5,0x56,0x56,0x5C,0x44,0x46,0x00},//毫 ( ~ S7 u1 R5 c, a1 }& E0 Z{0x00,0x10,0x50,0x50,0x50,0xE0,0xB0,0xB0,0x90,0x10,0x30,0x00}, 2 F* j0 r ^# w% f" f8 ~! e{0x7F,0x44,0x44,0x7F,0x00,0x10,0x12,0x11,0x10,0xFF,0x10,0x00},//时 {0xE0,0x40,0x40,0xE0,0x00,0x00,0x00,0x90,0x10,0xF0,0x00,0x00}, 1 w3 V) C ~5 n) r8 |{0x04,0x08,0x34,0xC4,0x07,0x04,0x04,0xC4,0x37,0x08,0x04,0x00},//分 4 Y( P5 H% H' w8 q* a; _{0x00,0x10,0x20,0xC0,0x00,0x10,0x10,0x10,0xE0,0x00,0x00,0x00}, {0x48,0x4B,0x7F,0x89,0x02,0x1C,0x00,0xFF,0x00,0x20,0x1D,0x00},//秒 {0x80,0x00,0xF0,0x00,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00}, 4 _/ ]6 K" T: P9 e{0x41,0x41,0x5D,0x55,0x55,0xD5,0x55,0x55,0x5D,0x41,0x41,0x00},//高 {0xF0,0x00,0x00,0x70,0x50,0x50,0x50,0x70,0x00,0x10,0xF0,0x00}, {0x04,0x08,0x3F,0xC0,0x7F,0x44,0x44,0x7F,0x84,0x84,0x04,0x00},//低 {0x00,0x00,0xF0,0x00,0xE0,0x40,0xA0,0x10,0xC0,0x20,0xF0,0x00}, % A6 [$ a( H1 m8 _5 ?{0x00,0x08,0x7B,0x08,0xFF,0x48,0x49,0x9F,0xB0,0xD7,0x90,0x9F},//频 , C I: x- P. U1 \{0x00,0x90,0x10,0x20,0x40,0x80,0x00,0x90,0x20,0xC0,0x20,0x90}, . x" W$ g* ?, T7 N- F{0x00,0x40,0x51,0x4A,0x59,0x6B,0xCD,0x4B,0x51,0x4A,0x51,0x40},//率 f0 D5 g2 T( i& a! U{0x00,0x40,0x40,0x40,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40}, - s! D/ f$ q/ P7 W& z{0x00,0x44,0x22,0x7F,0x40,0x5F,0x40,0x7F,0x00,0x3F,0x00,0xFF},//测 * d2 s: P5 S( n" w x{0x00,0x20,0x40,0x90,0x20,0xC0,0x20,0x90,0x00,0x80,0x10,0xF0}, 7 ~5 ~4 O4 ?: ?2 D6 b& Y{0x00,0x10,0xFF,0x95,0x95,0x95,0xDF,0xB5,0x95,0x95,0xFF,0x10},//量 3 p/ ` I1 B; @; v) d, V1 X{0x00,0x10,0x50,0x50,0x50,0x50,0xF0,0x50,0x50,0x50,0x50,0x10}, . ~# y: ~/ }' H, o; f}; ) k6 L8 i; K& w) l7 n//Write Plus $ v" n4 P0 _$ tvoid wri(void){ 8 |, j6 o0 a% C; ]" L HAL_GPIO_WritePin(GPIOB,LCDCLK,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB,LCDCLK,GPIO_PIN_SET); , m) \$ L( ~+ {! |# B# T% [} $ Y8 q0 M4 v$ ]//a byte data to lcd||dt=data reg=command void b2l(unsigned char dt,unsigned charcom){ 1 J0 X$ t+ }% g8 _ unsigned char i; if(com)HAL_GPIO_WritePin(GPIOB,LCDREG,GPIO_PIN_SET);elseHAL_GPIO_WritePin(GPIOB,LCDREG,GPIO_PIN_RESET);; for(i=0;i<8;i++){ if(dt&0x80){HAL_GPIO_WritePin(GPIOB,LCDDIN,GPIO_PIN_SET);}else{HAL_GPIO_WritePin(GPIOB,LCDDIN,GPIO_PIN_RESET);}; ( n. x) \5 |4 a T: X dt=dt<<1; " h$ H( a# v" O- b8 C wri(); } y5 m1 D7 H" q- l4 y} //Set display X,Y 4 N; y% W4 g- r8 s2 d; V2 pvoid setXY(unsigned char X,unsigned charY){ b2l(0x40+Y,0);//column & W4 ^, J3 z8 L2 V- l4 W7 R b2l(0x80+X,0);//row } //LCD Clear 2 H8 ]- x/ j( G$ _, Q8 ?void lcdClear(void){ unsigned char t,k; ( o0 x! l/ j. u/ T4 s F setXY(0,0); for(t=0;t<9;t++){for(k=0;k<102;k++){b2l(0x00,1);}} , P. @* y1 h4 p, i1 I} % c0 U S/ Q, D% q5 U; J% F# c" H1 X//Display ASCII ' l+ H8 i) ]( _7 g/ Svoid c2l(unsigned char x,unsigned chary,unsigned char c){ unsigned char line; 8 q9 Y7 Z. [: n4 g setXY(x*6,y); 3 [* \* ?, q# v8 Y for(line=0;line<6;line++)b2l(asc2[c][line],1); } //Display Hanzi 5 ^; K- p$ b/ k0 u$ s1 g9 Svoid h2l(unsigned char row,unsigned charpage,unsigned char c){ unsigned char i; 1 h& g5 \; B. }; S7 Y- }5 S* Z setXY(row*6,page); 0 n3 R$ B5 K' N$ c for(i=0;i<12;i++){b2l(hanzi[c*2],1);} . o6 g" V; Z6 ~ setXY(row*6,page+1); 1 D9 D( R3 Q4 Q3 ]! ^1 } for(i=12;i<24;i++){b2l(hanzi[c*2],1);} + ]5 t, B, B; m' x" b l0 {} //Initial 6903 LCD model void lcdInit(void){ HAL_GPIO_WritePin(GPIOB,LCDRES,GPIO_PIN_RESET); + Q) [* v; ?# n* { HAL_Delay(10); HAL_GPIO_WritePin(GPIOB,LCDRES,GPIO_PIN_SET); HAL_Delay(10); b2l(0x25,0);//00100 PD=1dcOn|=0DcoffV=0Up|=1Left H==1 9 _- O* a2 \' g0 ^. `# g3 z HAL_Delay(1); b2l(0x15,0);//plus=L000~111=1/6-1/7-1/8-1/9//14=1/7 ! T5 q6 M4 B/ P1 S2 x3 N" | HAL_Delay(1); b2l(0x9C,0);//Set VOP , j8 {2 z. J, e$ `% B HAL_Delay(1); b2l(0x20,0);//PD=0,V=2,H=0 //Test LCD 8 l. M' c8 w3 J: |: [2 A* S //b2l(0x09,0);//08+/09=All Black/08=AllWrite/0C=Noamal/0D=Invert //wait(1.0f); - Z2 L, S( y/ V/ R& _8 E4 i5 ]! D+ f b2l(0x0C,0);//LCD Set Final + k& a4 _0 Z( b; W/ N HAL_Delay(10); } //Display ASCII Test {/ b2 _' _, U/ h$ Lvoid dispAsc(void){ + S, c1 Q( p2 g* W: _% o inti,j,k=0; for(i=0;i<8;i++){ / g, K& P. N/ P9 Q! v- l0 P for(j=0;j<17;j++){ c2l(j,i,k); if(k>39){k=0;}else{k++;} 7 n& x% l! J/ P- {$ L, a } ( p6 @' M( S8 I; F1 O/ j } + t0 r4 u; ?9 z: ~" A} / y) m9 H2 I! s; M s//Display Hanzi Test , d. s" _3 X5 D# L4 H- |void dispHz(void){ ; p# B7 \5 Y* z k; C inti,j,k=0; 5 B1 @8 n5 G; u6 i! t, E# i9 R for(i=0;i<8;i+=2){ for(j=0;j<16;j+=2){ 7 T2 h5 g+ @ V" q9 Q h2l(j,i,k); if(k>28){k=0;}else{k++;} , o) ^0 N. B# X* Z } } 5 Y5 j# K# \$ y4 h4 T2 W8 J/ W} / l) m! I' `! L" W( x D5 O' [//END Files// 将以前在其他芯片上通过的6903驱显代码修改一下,include到主函数前部: 3 v( b. L' |& B#include "6903.h" " c" g5 M4 j, {2 C9 G之后添加整形定义: 7 w4 ?4 J! o8 O' k& }( N \! cint k=0; 再在main.c中的main主函数中添加: lcdInit(); lcdClear(); 在while循环体重添加: ! T. t. ?8 z" n+ b8 K) HdispAsc(); # a# j5 ?& q9 H# E; K) [HAL_Delay(1500); / U+ u: z9 l' {2 x" K# F# a) d, |lcdClear(); dispHz(); HAL_Delay(1500); . s# R; s0 |6 W6 g0 o" m: f# flcdClear(); 编译下载后的结果见照片1-2,1-3。 至此GPIO测试完成。如果想让板载LED也亮(接在GPIOA的A_5口上),则可以在main.h中加入: #define LED GPIO_PIN_5 7 T2 v# f0 x4 v- }) n, d7 ]$ {#define LEDPORT GPIOA 在main.c的static void MX_GPIO_Init(void)函数中加入: 0 h% Q. O9 G1 l6 }//LED PIN 9 h, _6 ]8 \2 ? GPIO_InitStruct.Pin = LED; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; % r- _. M! s R HAL_GPIO_Init(LEDPORT, &GPIO_InitStruct); % ~3 }, Z; T. m; s, b在循环体中加入: : b& w9 z2 L# n. ?; HHAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5); ( `1 q+ C$ R o; M n+ ?编译下载即可,LCD驱显二圈,LED闪亮一次。 下边将采用ST公司极力推荐的用创建工程工具STM32CubeMX来开始自己创建工程实现目标。本例采用驱动芯片的某些功能的方法进行测试和实验 8 K3 s* n9 B4 x: W- t<STM32G431测试>二、搭建实验平台 实验平台: ( l4 M; i5 G) _" EPC:联想商务一体机,3代I3酷睿芯片,2G ram,2T硬盘,自己加装了SSD硬盘作为系统盘,系统是Windows 7 旗舰,64位企业版。 9 b* c0 k5 ?5 j$ d/ L0 ~' \从网上搜下载了STM32CubeMX_v5-3-0.rar,顺利安装在计算机中,这样计算机中有4.23,4.50,5.30三个版本,尽管向下兼容,还是留着将来看看他们的区别吧。 + o2 v& r7 h3 g. X) ?在创建工程是,MX要求联网下载ATM32G系列的设备文件,这个过程稍长了一点,但很快就完成了。 本实例创建的工程为STM32G431,可以同时生成Keil和IAR的工程文档,由于在IAR官网找不到STM32G431RB的设备驱动文件,只好在Keil中开发。本机安装有Keil5.23 和5.25两个版本,都能正常运行。 Keil中需要安装Link V3版本的,网上搜了stsw-link004.zip、stsw-link007.zip、stsw-link009.zip,经过测试本机安装stsw-link007.zip时Keil5.23和Keil5.25均可正常编译和下载。 6 ^ A0 \/ u5 w) D) c. ~同时搜了两个工程文档包,做了实验一,点亮LCD和LED。 $ G/ D0 Y$ N3 \0 ^8 k* A计划创建工程测试完成:3路ADC、2路DAC、4路PWM信号、3~4路外部触发控制、1路UART、1路I2C、1路模拟串口驱显LCD(此实验已完成,本例拿来主义)。 " v. ?3 S% n, d' t; `. I具体创建过程遇到许多问题,最主要的是由于STM芯片支持正交网络开关变换GPIO引脚的功能,带来方便的同时也带来初始设置时的管脚冲突,上述模块在GPIO口的应用中检查设置了这个产生冲突,再重新变换引脚,最后测试缩减为: ADC1的IN8一路ADC测试,PC_2口 8 w+ N8 |8 U+ y% q0 S由TIM6中断触发DAC1的两路输出,PA_4,PA_5输出,其中正好与板上的LED连接驱显亮暗 8 g3 L5 W* J5 U# j- X) x由TIM2的通道4输出一路PWM信号,TIM3的通道4输出一路PWM信号,一共两路PWM输出(实际上4路也没有问题,已经过实测) 1路I2C,由I2C3实现 两路UART,一路LPUART、一路USART3,都可以正常收发 / l5 p3 Q- E6 t0 @# p设置了Systick,以实现由此时钟控制操作,本例实现程序计数器的功能 + Y6 ^; N+ Z$ L# r/ b) c所有模块都已实现,除了ADC采用TIM15外部触发启动ADC工作,所有的模块都采用DMA和中断自动运行过程。 % m* i# A" n" j1 F由于工程设置是一次完成,逐项测试的,所以只能将成功的设置截图显示,并且结果对应照片显示。 / X& x' p4 ^1 V0 y: ^1 b ADC1和TIM15的设置见截图2_01~2_08,由于设置界面过多只截取首个。 图2_01 图2_02 # X+ z& w' S$ o9 I2 R 图2_03 图2_04 图2_05 : e* }+ f8 e/ O2 i! J- b4 O4 A2 \: ^; P% C3 u! A- k$ [4 \& @ 3 `* v6 M/ r1 n& g7 s ! R8 s: s+ ^# S( Y+ \, G 7 L+ x/ y. U6 |+ J* @图2_06 0 }7 n$ c0 m0 L. s 图2_07 图2_08 / M/ k# m5 Z8 C) e, P _ DAC1和TIM6的设置见截图2_09~2_15,截图同理。 图2_09 , C2 o* O! m, Z# ^0 j S9 Q. G P7 o% }) T; R0 J- H7 M1 z 图2_10 图2_11 9 E8 z k! j0 ^1 O2 H: a! [图2_12 $ j8 u- f9 \3 H1 Y1 P$ V ( ~! {+ M6 R% k' R) `+ p/ F$ \1 @ 图2_13 图2_14 图2_15 - \$ D# p- Y, P7 N* ` PWM1,与PWM2之事两个不同时钟,设置基本类似,截一个的设置图,见截图2_16~2_19。 " Z+ u' A F& ` I 图2_16 图2_17 2 F2 T" Y0 |2 g/ B% Z7 O5 @$ \, U1 { 图2_18 图2_19 ; |7 U! k/ x; { & ] S9 C: g9 \( \; b1 i! P $ C9 D3 U) p5 M% ~( u9 j& b6 e ) ~* t' W; W" w" T6 N2 `I2C3的设置除了Paramenter Setting之外,其他的设置都基本相同,勾选NVIC Setting、DMA、定义GPIO口标名,见截图2_20。以下的除了特殊的都大同小异,免截图了。 图2_20 $ n9 L) d0 N+ i- l8 L* y" {0 E ?" s1 H X6 Q/ n, ] 回到左栏的System Core,点Code Generation,将下边的所有勾选上,点NVIC,将所有除了系统默认的其他中断允许勾上,以便自动运行中断服务。在PreemptionPriority下边的中断号默认为0,可以按照需要重新划分等级,0~7级,0级最优先。本例全默认都为0级。见图2_21~2_22。 1 @; d, ?/ @+ [ ) n0 @ v. u0 x 图2_21 图2_22 . t5 ]6 @2 l, ~& t2 z7 U2-1驱显LCD 因为与实验一一样此处不再嗷述,之事在4线模拟串口先事先定义GPIO口的名称分别为:LCDDAT、LCDREG、LCDCLK、LCDRES,这样改变任意模拟串口只需要改变硬件接线即可,代码不用更改。 ' ~" p* @6 W3 \/ D/ R8 O2-2测试Systick 7 J8 X; h7 ~; N" a( K& W& o3 ]本例仅仅由Systick中断任务完成程序计数器增一的功能,显示在LCD中,由于速度较快,显示在第3位可以差不多看见。 1 P# b, V& F. e* z# F由于以前的STM32CubeMX就有不能自动在stm32g4xx_it.c中生成开Systick中断句柄语句,所以必须手动加入,加在voidSysTick_Handler(void)函数中: : O5 v+ \ g1 p. o; a( x" _) ~HAL_IncTick();//这句原有 3 f$ E" @# s J% X/ k! {' ~- dHAL_SYSTICK_IRQHandler();//这句后加 这样在main前边加入采用回访中断的宏: void HAL_SYSTICK_Callback(void){if(js>9999999)js=0;else js++;} 这样在主函数显示jsq变量就可以实现了。以下的所有LCD照片都可以看到JSQ的增加。 / B3 Z8 t4 W( ^$ }6 v: |$ B5 k2-3测试PWM 本实例设置了两路PWM分别由Timer2的通道4和Timer的通道4输出,可以改变tim.c中的如下语句实现PWM输出频率: htim2.Init.Prescaler = 1000;//改变输出频率 htim2.Init.Period = 100;//改变脉宽周期 3 R! `; n6 h/ s) U& {! v+ T! |! S. Y在main函数中用如下语句启动PWM: HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);//PB_11 HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);//PB_1 8 I* P! L3 K* ?自编一个函数改变PWM的脉宽,由循环语句调用: void pwmTest(void){ if(pwm1<250)pwm1+=5;elsepwm1=1;TIM2->CCR4=pwm1;//PB_11 if(pwm2<120)pwm2+=2;elsepwm2=1;TIM3->CCR4=pwm2;//PB_1 s0 x) u/ j: B `& V0 Y} TIMx——表示Timer,CCRx表示输出通道,别错了! 2 O" J+ U, r4 Q; T& A4 U( B 不调用时的PWM波形见照片2_23;调用pwmTest()函数时的波形见照片2_24。尽管只是一路,另一路结果是一样的。 图2_23 图2_24 6 ~ Q, [8 e6 x Y+ z5 U2-4测试DAC 4 z2 F$ a- P1 a o" r本实例开通了一个DAC的2个通道,可以输出两路DAC信号,设置中DAC1通道2用了三角形输出方式,所以得到的是锯齿波形,而DAC 通道1设置输出白噪声模式。 9 A5 p; o- K: `8 S9 g( G" g, H! V N由于设置为DMA自动传输初始值,中断循环执行,设置代码在while循环体外,代码: //Set & run DAC c- T" l9 J9 u/ VHAL_TIM_Base_Start(&htim6); / ]. B4 _7 y) C, s0 Z, t4 j sHAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&Samples_In,5000,DAC_ALIGN_12B_R); + L' I# t, h+ z+ F6 p5 u+ ^$ c- ?- rHAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_2,(uint32_t*)&Samples_In,5000,DAC_ALIGN_12B_R); 结果是通道1输出的是一个1/2VDD高电平,不知何因。结果见照片2_25。 ( _) {1 P& ]5 y( j7 d3 ^: C3 O% \3 g* t$ T: l 图2_25 而通道二连接在PA_5上正好是一只LED,设置为三角波(锯齿波)以便驱显LED。 当设置DAC的Maximum Trianggle Amplitude为4095——满幅值时出现跳变,见照片2_26,可以看到LED渐亮渐暗的过程。设置为其他的诸如2047,1023等就是一个非常好的三角波或锯齿波,LED不渐变了,见照片2_27。截图2_28是虚拟串口获得的数据,截图2_29是数据结果Excel处理成图形的结果。 + K+ a4 x% M# A3 ]2 \# ]$ u( Y( v$ V 图2_26 图2_27 图2_28 图_29 * d3 W& G0 m6 O* A2-5测试GPIO事件中断响应 5 Z: c6 f, P7 e, K. C& _本案例设置了3个Ext Int外部事件中断,有回调函数完成,因此代码写在main外边即可(本例为高电平触发,完成增一),代码: //Test ExtIntrupter KEY ' k7 w1 g; N( w) Pvoid HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ if(GPIO_Pin &K1_PB5_Pin){key[0]++;}//PB_5 if(GPIO_Pin &K2_PB6_Pin){key[1]++;}//PB_6 if(GPIO_Pin &K3_PC7_Pin){key[2]++;}//PC_7 } 0 F; [! x s5 d0 Y1 I2 ?$ V8 n: h$ g2 `7 ]* t' I6 e Zhaopian 2_30~2_32是采用尖镊子利用人体感应信号分别触发PB5,PB6,PC7产生计数,照片中K=右边第1~3分别为PB5,PB6,PC7的计数值。 图2_30 图2_31 图2_32 2-6 LPUART1和USART3测试 这项测试也废了一些时间,还是容易实现的,本实例采用115200bps,DMA传输,中断自动循环。没有配置出来printf函数,只能用HAL库提供的语句: ' [+ v/ A0 m7 tHAL_UART_Transmit(&huart3,(uint8_t *)prtCode,10,100); & t3 y: O/ Q, E$ H+ F1 ahauart3是从USART3输出到外部串口的RX,改成hlpuart1就可以从LPUART输出了。 & e+ c+ C8 Q0 Z! z比较麻烦的是这个代码只能输出16进制,为了能测试输出ADC采样,编写了一段代码进行转换成ASCII码,因为最大是4095,因为设置了超采样为8192,4位十进制就够了,函数: void h2b(void){ prtCode[4]=(adcx[0]/1000)%10+0x30; ' x; o, K9 \& p0 Y4 S. l/ l prtCode[5]=(adcx[0]/100)%10+0x30; 2 t& ?7 v7 S j3 E. \5 ~5 m' @ prtCode[6]=(adcx[0]/10)%10+0x30; prtCode[7]=(adcx[0])%10+0x30; ! V& R7 ?' c0 ^' t6 c: _} " ?, _: H8 Z/ ^& d1 U- A- u前边定义的uint8_tprtCode[]={0x41,0x44,0x30,0x3D,0x30,0x30,0x30,0x30,0x0A,0x0D}; 0 `& {/ q# V/ s4 g) {前3个是AD0,第4是=,最后两个是回车的ASCII代码,此函数改变从0算起的第4~7 为实际ADC的数值,因为设置了超采样1位,所以显示的最大数值是0~8191。结果见截图2_33。 # q+ d; i7 V7 K$ | 图2_33 6 t- _1 b( s1 q' S8 [& yT" m! n# `( O 4 l) ^& N6 j c$ z$ ~3 q+ D: a0 M 当设置DAC为2047时的波形为:Excel截图2_34,采样信号2_35。 ' c4 X* [2 J3 `* V2 B $ l( j/ a0 K$ o, t - Z$ x, ]8 @, x图2_34 图2_35 + C4 H" ?4 X+ N; |( G2-7 I2C3测试 I2C的测试比较简单,本实例省略了。 <STM32G431测试>三、总结 & J+ Q! i# z7 ?$ [7 D0 q1 k通过从采用STM32CubeMX创建工程开始,设计基本实验到初步调通每个基础实验的实现和在创建MX工程中的选设参数逐步明确了一些各一公共遵守的地方以便加快自己在新的芯片或开发板上实现预设功能。有以下几点需要注意: ) x& Q+ T2 b' ]: {1 }3 u% H8 X : Z8 R5 v* p9 S3 w6 r 3-1:由于GPIO复用,在设置新功能是会造成已设置的功能出现黄色覆盖,鼠标指向会出现状态提示,如图3_01,如果是IO冲突,必须模块IO改变或重新选设。 图3——01 3-2 Interupt的开通是需要先将模块的NVIC选设了,最后再在SystemCore中逐一勾选。 3-3 GPIO最好命名,可以在每个功能模块设置中命名,也可以在最后在System Core中逐一命名。 3-4 DMAmoren shi Normal,通常设置为循环。 3-5 系统时钟树的设置不复杂,只要选好系统时钟,在右边的时钟树输出到模块满足各个模块的最高工作频率以内即可。 T4 J/ T% T0 s* I2 H# m 3-6最后输出工程时,首次必须在Project Manager/Code Generator正确选择,如图3_02。 图3_02 当然实际设置遇到的问题远比这多,需要仔细斟酌选设,可以用不同的参数设置后生成工程代码运行检测找出最佳的。最后一点,检查到相关的网站学习获得帮助和提高积累经验非常重要。 由于是从Word文档中拷贝过来的,发现图对不上,只能参考吧.如果在玩这些有问题可以互相讨论学习,谢谢., y2 f% @# a5 W; S: E( [ |
STM32固件库分享,超全系列整理
【经验分享】STM32G4_CORDIC与定点带符号整数数据格式
STM32的CAN FD位定时设置注意事项
基于STM32G474 中 Triggered-half 模式的实现
基于STM32G4的数字控制 15kW双向PFC
基于STM32G431简介
今天14:00 | 基于STM32的MATLAB电机控制方案直播
基于STM32G474外红外接收经验分享
STM32G431RBT6之Key模块入门
STM32G431RBT6--LED模块入门
你上传成功了么