论坛» 嵌入式开发» MCU

助工
2023-04-11 14:36 11楼

串口中断模式与电脑收发测试如下:

相关函数如下:

image.png


串口1中断模式与电脑收发测试程序如下:

#include"config.h"

#include"STC32G_GPIO.h"

#include"STC32G_UART.h"

#include"STC32G_NVIC.h"

#include"STC32G_Delay.h"

#include"STC32G_Switch.h"

/*************功能说明**************

双串口全双工中断方式收发通讯程序。

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回, 默认波特率:115200,N,8,1.

通过开启UART.h 头文件里面的 UART1~UART4 定义,启动不同通道的串口通信。

用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度。

下载时, 选择时钟 22.1184MHz (用户可在"config.h"修改频率).

******************************************/

/*************本地常量声明**************/

/*************本地变量声明**************/

/*************本地函数声明**************/

/************* 外部函数和变量声明 *****************/

/******************* IO配置函数 *******************/

voidGPIO_config(void)

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义

GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1;//指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7

GPIO_InitStructure.Mode = GPIO_PullUp;//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);//初始化

}

/*************** 串口初始化函数 *****************/

voidUART_config(void)

{

COMx_InitDefineCOMx_InitStructure;//结构定义

COMx_InitStructure.UART_Mode = UART_8bit_BRTx;//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx

COMx_InitStructure.UART_BRT_Use = BRT_Timer1;//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)

COMx_InitStructure.UART_BaudRate = 115200ul;//波特率, 一般 110 ~ 115200

COMx_InitStructure.UART_RxEnable = ENABLE;//接收允许, ENABLE或DISABLE

COMx_InitStructure.BaudRateDouble = DISABLE;//波特率加倍, ENABLE或DISABLE

UART_Configuration(UART1, &COMx_InitStructure);//初始化串口1 UART1,UART2,UART3,UART4

NVIC_UART1_Init(ENABLE,Priority_1);//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

UART1_SW(UART1_SW_P30_P31);//UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44

}

/**********************************************/

void main(void)

{

u8i;

WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快

EAXSFR();//扩展SFR(XFR)访问使能

CKCON = 0; //提高访问XRAM速度

GPIO_config();

UART_config();

EA = 1;

PrintString1("STC32G UART1 Test Programme!\r\n");//UART1发送一个字符串


while (1)

{

delay_ms(1);

if(COM1.RX_TimeOut > 0)//超时计数

{

if(--COM1.RX_TimeOut == 0)

{

if(COM1.RX_Cnt > 0)

{

for(i=0; iTX1_write2buff(RX1_Buffer[i]);//收到的数据原样返回

}

COM1.RX_Cnt = 0;

}

}

}

}

编译如下:

7.png

下载串口程序,成功发送数据如下:

群.png





助工
2023-04-12 16:16 12楼

多路ADC转换-串口输出结果测试如下:

相关函数:

1.png

2.jpg


程序如下:

#include"config.h"

#include"STC32G_GPIO.h"

#include"STC32G_ADC.h"

#include"STC32G_UART.h"

#include"STC32G_Delay.h"

#include"STC32G_NVIC.h"

#include"STC32G_Switch.h"

/*************功能说明**************

本程序演示16ADC查询采样,通过串口1(P3.0,P3.1)发送给上位机,波特率115200,N,8,1

需要在"STC32G_UART.h"里设置:#definePRINTF_SELECT UART1

用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度。

下载时,选择时钟22.1184MHz (可以在配置文件"config.h"中修改).

******************************************/

/*************本地常量声明**************/

/*************本地变量声明**************/

/*************本地函数声明**************/

/*************外部函数和变量声明*****************/

/******************* IO配置函数*******************/

voidGPIO_config(void)

{

P0_MODE_IN_HIZ(GPIO_Pin_LOW | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);//P0.0~P0.6设置为高阻输入

P1_MODE_IN_HIZ(GPIO_Pin_All);//P1.0~P1.7设置为高阻输入

P3_MODE_IO_PU(GPIO_Pin_0 | GPIO_Pin_1);//P3.0,P3.1设置为准双向口

}

/******************* AD配置函数*******************/

voidADC_config(void)

{

ADC_InitTypeDefADC_InitStructure;//结构定义

ADC_InitStructure.ADC_SMPduty = 31;//ADC模拟信号采样时间控制, 0~31(注意:SMPDUTY一定不能设置小于10

ADC_InitStructure.ADC_CsSetup = 0;//ADC通道选择时间控制0(默认),1

ADC_InitStructure.ADC_CsHold = 1;//ADC通道选择保持时间控制0,1(默认),2,3

ADC_InitStructure.ADC_Speed = ADC_SPEED_2X16T;//设置ADC工作时钟频率ADC_SPEED_2X1T~ADC_SPEED_2X16T

ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;//ADC结果调整,ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED

ADC_Inilize(&ADC_InitStructure);//初始化

ADC_PowerControl(ENABLE);//ADC电源开关, ENABLEDISABLE

NVIC_ADC_Init(DISABLE,Priority_0);//中断使能, ENABLE/DISABLE;优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

}

/***************串口初始化函数*****************/

voidUART_config(void)

{

COMx_InitDefineCOMx_InitStructure;//结构定义

COMx_InitStructure.UART_Mode = UART_8bit_BRTx;//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx

COMx_InitStructure.UART_BRT_Use = BRT_Timer1;//选择波特率发生器, BRT_Timer1,BRT_Timer2 (注意:串口2固定使用BRT_Timer2)

COMx_InitStructure.UART_BaudRate = 115200ul;//波特率, 110 ~ 115200

COMx_InitStructure.UART_RxEnable = ENABLE;//接收允许, ENABLEDISABLE

UART_Configuration(UART1, &COMx_InitStructure);//初始化串口UART1,UART2,UART3,UART4

NVIC_UART1_Init(ENABLE,Priority_1);//中断使能, ENABLE/DISABLE;优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

UART1_SW(UART1_SW_P30_P31);//UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44

}

/**********************************************/

void main(void)

{

u8i;

u16j;

WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快

EAXSFR();//扩展SFR(XFR)访问使能

CKCON = 0; //提高访问XRAM速度

GPIO_config();

UART_config();

ADC_config();

EA = 1;

printf("STC32G AD to UART Test Programme!\r\n");//UART发送一个字符串

while (1)

{

for(i=0; i<16; i++)

{

delay_ms(200);

//Get_ADCResult(i);//参数0~15,查询方式做一次ADC,丢弃一次

j = Get_ADCResult(i);//参数0~15,查询方式做一次ADC,返回值就是结果, == 4096为错误

printf("AD%02d=%04d ",i,j);

if((i & 7) == 7)printf("\r\n");

}

printf("\r\n");

}

}

编译如下:

5.png

烧录到芯片后,下载软件上发送数据测试如下:

7.png


助工
2023-04-13 16:52 13楼

测试EEPROM如下:

相关函数如下:


通过串口发送命令读写EEPROM测试程序如下:

#include "config.h"
#include "STC32G_GPIO.h"
#include "STC32G_UART.h"
#include "STC32G_NVIC.h"
#include "STC32G_Delay.h"
#include "STC32G_EEPROM.h"
#include "STC32G_Switch.h"

/************* 本程序功能说明 **************

通过串口2(P4.6 P4.7)对STC内部自带的EEPROM(FLASH)进行读写测试。

FLASH做扇区擦除、写入、读出的操作,命令指定地址。

默认波特率: 115200,N,8,1.

串口命令设置: (命令字母不区分大小写)
E 0x000040 --> 对0x000040地址扇区内容进行擦除.
W 0x000040 1234567890 --> 对0x000040地址写入字符1234567890.
R 0x000040 10 --> 对0x000040地址读出10个字节数据.

注意:下载时,下载界面"硬件选项"中设置用户EEPROM大小,

并确保串口命令中的地址在EEPROM设置的大小范围之内。

下载时, 选择时钟 22.1184MHz (可以在配置文件"config.h"中修改).

******************************************/

#define Max_Length 100 //读写EEPROM缓冲长度

/************* 本地常量声明 **************/


/************* 本地变量声明 **************/
u8 tmp[Max_Length]; //EEPROM操作缓冲


/************* 本地函数声明 **************/


/************* 外部函数和变量声明 *****************/


/******************* IO配置函数 *******************/
void GPIO_config(void)
{
P4_MODE_IO_PU(GPIO_Pin_6 | GPIO_Pin_7); //P4.6,P4.7 设置为准双向口
}

/*************** 串口初始化函数 *****************/
void UART_config(void)
{
COMx_InitDefine COMx_InitStructure; //结构定义
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer2; //选择波特率发生器, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
UART_Configuration(UART2, &COMx_InitStructure); //初始化串口 UART1,UART2,UART3,UART4
NVIC_UART2_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

UART2_SW(UART2_SW_P46_P47); //UART2_SW_P10_P11,UART2_SW_P46_P47
}

/**********************************************/

u8 CheckData(u8 dat)
{
if((dat >= '0') && (dat <= '9')) return (dat-'0');
if((dat >= 'A') && (dat <= 'F')) return (dat-'A'+10);
if((dat >= 'a') && (dat <= 'f')) return (dat-'a'+10);
return 0xff;
}

//========================================================================
// 函数: u32 GetAddress(void)
// 描述: 计算各种输入方式的地址.
// 参数: 无.
// 返回: 32位EEPROM地址.
// 版本: V1.0, 2013-6-6
//========================================================================
u32 GetAddress(void)
{
u32 address;
u8 i,j;

address = 0;
if((RX2_Buffer[2] == '0') && (RX2_Buffer[3] == 'X'))
{
for(i=4; i<10; i++)
{
j = CheckData(RX2_Buffer
);
if(j >= 0x10) return 0xffffffff; //error
address = (address << 4) + j;
}
return (address);
}
return 0xffffffff; //error
}

/**************** 获取要读出数据的字节数 ****************************/
u8 GetDataLength(void)
{
u8 i;
u8 length;

length = 0;
for(i=11; i
{
if(CheckData(RX2_Buffer) >= 10) break;
length = length * 10 + CheckData(RX2_Buffer);
}
return (length);
}

/********************* 主函数 *************************/
void main(void)
{
u8 i,j;
u32 addr;
u8 status;

WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXSFR(); //扩展SFR(XFR)访问使能
CKCON = 0; //提高访问XRAM速度

GPIO_config();
UART_config();
EA = 1;

PrintString2("STC32系列单片机EEPROM测试程序,串口命令设置如下:\r\n"); //UART2发送一个字符串
delay_ms(5); //等待串口数据发送完成
PrintString2("E 0x000040 --> 对0x000040地址扇区进行擦除\xfd.\r\n"); //UART2发送一个字符串
delay_ms(5); //等待串口数据发送完成
PrintString2("W 0x000040 1234567890 --> 对0x000040地址写入字符1234567890.\r\n"); //UART2发送一个字符串
delay_ms(5); //等待串口数据发送完成
PrintString2("R 0x000040 10 --> 对0x000040地址读出10个字节内容.\r\n"); //UART2发送一个字符串
delay_ms(5); //等待串口数据发送完成
while(1)
{
delay_ms(1); //每1毫秒执行一次主循环,也可以使用定时器计时
if(COM2.RX_TimeOut > 0) //判断超时计数器
{
if(--COM2.RX_TimeOut == 0)
{
// printf("收到内容如下: ");
// for(i=0; i
// printf("\r\n");

status = 0xff; //状态给一个非0值
if((COM2.RX_Cnt >= 10) && (RX2_Buffer[1] == ' ')) //最短命令为10个字节
{
for(i=0; i<10; i++)
{
if((RX2_Buffer >= 'a') && (RX2_Buffer <= 'z')) RX2_Buffer = RX2_Buffer - 'a' + 'A'; //小写转大写
}
addr = GetAddress();
if(addr < 0x00ffffff) //限制地址范围
{
if(RX2_Buffer[0] == 'E') //判断指令类型是否为“E”擦除指令
{
EEPROM_SectorErase(addr); //擦除扇区
PrintString2("已擦除\xfd扇区内容!\r\n");
status = 0; //命令正确
}

else if((RX2_Buffer[0] == 'W') && (RX2_Buffer[10] == ' ')) //判断指令类型是否为“W”写入指令
{
j = COM2.RX_Cnt - 11;
if(j > Max_Length) j = Max_Length; //越界检测
//EEPROM_SectorErase(addr); //擦除扇区
EEPROM_write_n(addr,&RX2_Buffer[11],j); //写N个字节
PrintString2("已写入");
if(j >= 100) {TX2_write2buff((u8)(j/100+'0')); j = j % 100;}
if(j >= 10) {TX2_write2buff((u8)(j/10+'0')); j = j % 10;}
TX2_write2buff((u8)(j%10+'0'));
PrintString2("字节!\r\n");
status = 0; //命令正确
}

else if((RX2_Buffer[0] == 'R') && (RX2_Buffer[10] == ' ')) //PC请求返回N字节EEPROM数据
{
j = GetDataLength();
if(j > Max_Length) j = Max_Length; //越界检测
if(j > 0)
{
PrintString2("读出");
TX2_write2buff((u8)(j/10+'0'));
TX2_write2buff((u8)(j%10+'0'));
PrintString2("个字节内容如下:\r\n");
EEPROM_read_n(addr,tmp,j);
for(i=0; i
TX2_write2buff(0x0d);
TX2_write2buff(0x0a);
status = 0; //命令正确
}
}
}
}
if(status != 0) PrintString2("命令错误!\r\n");
COM2.RX_Cnt = 0;
}
}
}
}

编译如下:

4.png

下载软件发送结果如下:

555.jpg

专家
2023-04-14 00:56 14楼

感谢分享

专家
2023-04-14 07:14 15楼

感谢分享

助工
2023-04-14 17:05 16楼

测试比较器如下:

相关函数如下:

利用P3.7做比较器正极输入源,内部1.19V或P3.6口做负极输入源程序如下:

#include "config.h"

#include "STC32G_GPIO.h"

#include "STC32G_NVIC.h"

#include "STC32G_Compare.h"

/************* 本地常量声明 **************/

/************* 本地变量声明 **************/

/************* 本地函数声明 **************/

/************* 外部函数和变量声明 *****************/

/************************ 比较器配置 ****************************/

void CMP_config(void)

{

CMP_InitDefine CMP_InitStructure; //结构定义

CMP_InitStructure.CMP_EN = ENABLE; //允许比较器 ENABLE,DISABLE

CMP_InitStructure.CMP_P_Select = CMP_P_P37; //比较器输入正极选择, CMP_P_P37/CMP_P_P50/CMP_P_P51, CMP_P_ADC: 由ADC模拟输入端做正输入.

CMP_InitStructure.CMP_N_Select = CMP_N_GAP; //比较器输入负极选择, CMP_N_GAP: 选择内部BandGap经过OP后的电压做负输入, CMP_N_P36: 选择P3.6做负输入.

CMP_InitStructure.CMP_InvCMPO = DISABLE; //比较器输出取反, ENABLE,DISABLE

CMP_InitStructure.CMP_100nsFilter = ENABLE; //内部0.1us滤波, ENABLE,DISABLE

CMP_InitStructure.CMP_Outpt_En = ENABLE; //允许比较结果输出,ENABLE,DISABLE

CMP_InitStructure.CMP_OutDelayDuty = 16; //比较结果变化延时周期数, 0~63

CMP_Inilize(&CMP_InitStructure); //初始化比较器

NVIC_CMP_Init(RISING_EDGE|FALLING_EDGE,Priority_0); //中断使能, RISING_EDGE/FALLING_EDGE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

}

/************************ IO口配置 ****************************/

void GPIO_config(void)

{

GPIO_InitTypeDef GPIO_InitStructure; //结构定义

GPIO_InitStructure.Pin = GPIO_Pin_6 | GPIO_Pin_7; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作

GPIO_InitStructure.Mode = GPIO_HighZ; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P3,&GPIO_InitStructure); //初始化

GPIO_InitStructure.Pin = GPIO_Pin_7; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作

GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P4,&GPIO_InitStructure); //初始化

}

/************************ 定时器配置 ****************************/

/******************** task A **************************/

void main(void)

{

WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快

EAXSFR(); //扩展SFR(XFR)访问使能

CKCON = 0; //提高访问XRAM速度

GPIO_config();

CMP_config();

EA = 1;

while (1);

}

编译如下:

6.png


共16条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]