MDKでC++ソースフォーマットを使用してprintfシリアルポート出力を行う場合、デバッグ中にカードが起動コードにあることを発見します.
usart.h
CPP
元のCファイルの中でコンパイルしてダウンロードした後に正常に運行して、しかしC++ファイルに変えた後にコンパイルしてダウンロードOK、しかし運行は正常ではありません.デバッグ中に死んだことに気づいた.s起動コードには図のように、(システム割り込み関数に入る前にカードが......?)観察したところUSART 1_IRQHandler()はブレークポイントを降りることができなくて、プログラムがそれを探し出せないようです....C++コンパイルされた関数名がCと違うことを考えて、ヘッダファイルにvoid USART 1_を明記してみましたIRQHandler(void)割り込み関数(ヘッダファイルに注記されている赤いフォント)は、コンパイルダウンロード実行OKであることから、自分の誤りはC++でCの割り込み関数を参照したはずであり、Cでコンパイルされた割り込み関数名とC++の不一致により、関数エントリが見つからないことがわかったので、参照したC形式の関数を明記する
CとC++の相互参照は注意しなければならない.
#ifndef __USART_H
#define __USART_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
//#include "stm32f4xx_conf.h"
#include "sys.h"
#define USART_REC_LEN 200 // 200
#define EN_USART1_RX 1 // (1)/ (0) 1
#define USART1_CH 'A'
#define PIN_USART1_TX 9
#define PIN_USART1_RD 10
#define GPIO_LINK_USART1 USART1_CH,\
GPIO_PIN_(PIN_USART1_TX)|GPIO_PIN_(PIN_USART1_RD),\
GPIO_Mode_AF,\
GPIO_Speed_50MHz,\
GPIO_OType_PP,\
<span style="white-space:pre"> </span> GPIO_PuPd_UP
#define printf Usart_Printf
extern u8 USART_RX_BUF[USART_REC_LEN]; // , USART_REC_LEN .
extern u16 USART_RX_STA; //
// ,
void usart_init(u32 bound);
void Usart_Printf(const char *fmt,...);
<span style="background-color: rgb(255, 255, 255);"><span style="color:#cc0000;">//void USART1_IRQHandler(void);</span>
</span>
#ifdef __cplusplus
}
#endif
#endif
CPP
void Usart_Printf(const char *fmt,...){
va_list ap;
int i = 0;
char string[256]={0};
va_start(ap,fmt);
vsprintf(string,fmt,ap);
while(string[i]!=0){
while((USART1->SR&0X40)==0);// ,
USART1->DR = (u8)string[i++];
}
va_end(ap);
}
#if EN_USART1_RX //
u8 USART_RX_BUF[USART_REC_LEN]; // , USART_REC_LEN .
u16 USART_RX_STA=0; // 0x8000 ,
void usart_init(u32 bound){
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);// USART1
GPIO_Link_Init(GPIO_LINK_USART1);
GPIO_PinAFConfig(GPIO(USART1_CH),PIN_USART1_TX,GPIO_AF_USART1); //GPIOA9 USART1
GPIO_PinAFConfig(GPIO(USART1_CH),PIN_USART1_RD,GPIO_AF_USART1); //GPIOA10 USART1
USART_InitStructure.USART_BaudRate = bound;//
USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 8
USART_InitStructure.USART_StopBits = USART_StopBits_1;//
USART_InitStructure.USART_Parity = USART_Parity_No;//
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //
USART_Init(USART1, &USART_InitStructure); // 1
USART_Cmd(USART1, ENABLE); // 1
USART_ClearFlag(USART1, USART_FLAG_TC);
#if EN_USART1_RX
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//
//Usart1 NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;// 1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;// 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; // 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ
NVIC_Init(&NVIC_InitStructure); // NVIC 、
#endif
}
void USART1_IRQHandler(void) // 1
{
u8 Res;
#ifdef OS_TICKS_PER_SEC // , ucosII .
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // ( 0x0d 0x0a )
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //
if((USART_RX_STA&0x8000)==0)//
{
if(USART_RX_STA&0x4000)// 0x0d
{
if(Res!=0x0a)USART_RX_STA=0;// ,
else USART_RX_STA|=0x8000; //
}
else // 0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;// ,
}
}
}
}
#ifdef OS_TICKS_PER_SEC // , ucosII .
OSIntExit();
#endif
}
#endif
元のCファイルの中でコンパイルしてダウンロードした後に正常に運行して、しかしC++ファイルに変えた後にコンパイルしてダウンロードOK、しかし運行は正常ではありません.デバッグ中に死んだことに気づいた.s起動コードには図のように、(システム割り込み関数に入る前にカードが......?)観察したところUSART 1_IRQHandler()はブレークポイントを降りることができなくて、プログラムがそれを探し出せないようです....C++コンパイルされた関数名がCと違うことを考えて、ヘッダファイルにvoid USART 1_を明記してみましたIRQHandler(void)割り込み関数(ヘッダファイルに注記されている赤いフォント)は、コンパイルダウンロード実行OKであることから、自分の誤りはC++でCの割り込み関数を参照したはずであり、Cでコンパイルされた割り込み関数名とC++の不一致により、関数エントリが見つからないことがわかったので、参照したC形式の関数を明記する
CとC++の相互参照は注意しなければならない.