jjzjj

HT32F52352单片机,双串口,PWM的4路输出,GPIO输入(红外模块)(可以当合泰杯比赛的程序模板,非常好用),printf使用自定义串口输出

黎临 2024-01-05 原文

先放出双串口的代码,很多时候我们要利用一个串口仿造写出另一个串口的时候,时而失败。我通过改了几次HT32的代码之后发现主要问题出现在宏定义这边。

usart.c文件

#include "usart.h"
#include "ht32f5xxxx_gpio.h"


/**************************实现函数********************************************
函数说明:配置usart串口

*******************************************************************************/ 
void USART_Configuration(void)
{
	 USART_InitTypeDef USART_InitStructure;
	 {                                                              
     CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
     CKCUClock.Bit.AFIO                   = 1;
     CKCUClock.Bit.PA = 1;			
     CKCUClock.Bit.USART1         = 1;			
     CKCU_PeripClockConfig(CKCUClock, ENABLE);
    }
  
	{                                                          
		 CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
		 CKCUClock.Bit.AFIO                   = 1;
		 CKCUClock.Bit.PA = 1;			
		 CKCUClock.Bit.USART0         = 1;			
		 CKCU_PeripClockConfig(CKCUClock, ENABLE);
	}
	 
  GPIO_PullResistorConfig(HT_GPIOA, GPIO_PIN_15, GPIO_PR_UP);    //记得这里也要改
	GPIO_PullResistorConfig(HT_GPIOA, GPIO_PIN_3, GPIO_PR_UP);

  AFIO_GPxConfig(GPIO_PA, AFIO_PIN_14, AFIO_FUN_USART_UART);//如果要使用数据线进行串口通信功能,把PA14 15改成PA4 5
  AFIO_GPxConfig(GPIO_PA, AFIO_PIN_15, AFIO_FUN_USART_UART);//并且把开发板的跳线帽接到Tx端
	AFIO_GPxConfig(GPIO_PA, AFIO_PIN_2, AFIO_FUN_USART_UART);
	AFIO_GPxConfig(GPIO_PA, AFIO_PIN_3, AFIO_FUN_USART_UART);

  /*
		波特率: 115200
		长度:   8bits
		停止位: 1位
	  校验位: 无			
	  模式:   正常模式
  */
		
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
  USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
  USART_InitStructure.USART_Parity = USART_PARITY_NO;
  USART_InitStructure.USART_Mode = USART_MODE_NORMAL;
  USART_Init(HT_USART1, &USART_InitStructure);
	USART_Init(HT_USART0, &USART_InitStructure);
  
		 //中断设置    
		NVIC_EnableIRQ(USART1_IRQn);
		NVIC_EnableIRQ(USART0_IRQn);
			
		USART_IntConfig(HT_USART1, USART_INT_RXDR, ENABLE);
		USART_IntConfig(HT_USART0, USART_INT_RXDR, ENABLE);
			
		// 使能 COM1_PORT  发送和接收 
		USART_TxCmd(HT_USART1, ENABLE);
		USART_RxCmd(HT_USART1, ENABLE);
		USART_TxCmd(HT_USART0, ENABLE);
		USART_RxCmd(HT_USART0, ENABLE);
	

	 	                                                                                      
//  USART_RXTLConfig(COM1_PORT, USART_RXTL_04); 设置FIFO接收等级

}


/**************************实现函数********************************************
函数说明:接收中断服务函数

*******************************************************************************/ 
void USART1_IRQHandler(void)			//串口1中断
{
	u8 data;
	
	if( USART_GetFlagStatus(HT_USART1, USART_FLAG_RXDR ) )         //接收中断
	{
		data = USART_ReceiveData(HT_USART1);                         //读取接收到的数据
		printf("data = %c\n",data);                                  //把收到的数据发送回电脑	
	}																																//发送多字节会多次进入中断
	USART_ClearFlag(HT_USART1,USART_FLAG_RXDR);
}

void USART0_IRQHandler(void)			//串口1中断
{
	u8 data;
	
	if( USART_GetFlagStatus(HT_USART0, USART_FLAG_RXDR ) )         //接收中断
	{
		data = USART_ReceiveData(HT_USART0);                         //读取接收到的数据
		Usart_Sendbyte(HT_USART0,data);                                 //把收到的数据发送回电脑		
	}																																//发送多字节会多次进入中断
	USART_ClearFlag(HT_USART0,USART_FLAG_RXDR);
}



void USART_Tx1(const char* TxBuffer, u32 length)
{
  int i;

  for (i = 0; i < length; i++)
  {
    while (!USART_GetFlagStatus(HT_USART1, USART_FLAG_TXC));
    USART_SendData(HT_USART1, TxBuffer[i]);
  }
}
void USART_Tx0(const char* TxBuffer, u32 length)
{
  int i;

  for (i = 0; i < length; i++)
  {
    while (!USART_GetFlagStatus(HT_USART0, USART_FLAG_TXC));
    USART_SendData(HT_USART0, TxBuffer[i]);
  }
}


/**************************实现函数********************************************
函数说明:发送一个字节

*******************************************************************************/ 
void Usart_Sendbyte(HT_USART_TypeDef* USARTx, u8 data)
{
	USART_SendData(USARTx, data);
	while (USART_GetFlagStatus(USARTx, USART_FLAG_TXDE) == RESET);		
}
 
/**************************实现函数********************************************
函数说明:发送数组

*******************************************************************************/ 
void Usart_SendArray(HT_USART_TypeDef* USARTx, u8 *array,u8 num)
{
	u8 i;
	for( i = 0;i < num;i++)
	{
		Usart_Sendbyte(USARTx,*array);
		array++;
	}
}
 /**************************实现函数********************************************
函数说明:发送字符串

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

void Usart_SendStr(HT_USART_TypeDef* USARTx, uint8_t *str)
{
	uint8_t i;
	for(i = 0;str[i] != '\0';i++)
	{
		Usart_Sendbyte(USARTx,str[i]);
	}
}

usart.h文件

#ifndef __USART_H
#define __USART_H 			   
#include "ht32f5xxxx_usart.h"
#include "sys.h"
#define USART_GPIO_GROUP             (GPIO_PA)
#define USART_TX_PIN                 (GPIO_PIN_4)
#define USART_RX_PIN                 (GPIO_PIN_5)
#define USART_AFIO_MODE              (AFIO_FUN_USART_UART) //默认模式:AFIO_MODE_DEFAULT ,AFIO_MODE_1~15对应模式1~15
#define COM1_PORT                    (HT_USART1)
#define COM0_PORT                    (HT_USART0)

void USART_Configuration(void);
void COM1_IRQHandler(void);
void Usart_Sendbyte(HT_USART_TypeDef* USARTx, u8 data);
void Usart_SendArray(HT_USART_TypeDef* USARTx, u8 *array,u8 num);
void Usart_SendStr(HT_USART_TypeDef* USARTx, uint8_t *str);
void USART_Tx1(const char* TxBuffer, u32 length);
void USART_Tx0(const char* TxBuffer, u32 length);
#endif

 我所发现的问题是这个宏定义,如果串口中断名改为

void COM0_PORT_IRQHandler(void)            //串口0中断

void COM1_PORT_IRQHandler(void)            //串口1中断

#define COM1_PORT                    (HT_USART1)
#define COM0_PORT                    (HT_USART0)

串口是无法进入中断,也就是无法接收信息的,但是可以正常发送,只要使用原本的中断名就会恢复正常接收,如下

void USART0_IRQHandler(void)             //串口0中断

void USART1_IRQHandler(void)             //串口1中断

主函数调用格式

#include "ht32.h"
#include "usart.h"
#include "delay.h"

int main(void)
{			
   int input=0;	  
   GPIOInout_CKCU_Configuration();                                                                                  
   USART_Configuration();
	
    printf("Loading Finished! %d\r\n", input);
	USART_Tx1(HelloString, sizeof(HelloString));
	USART_Tx0(HelloString, sizeof(HelloString));
  while (1)
  {	
    
  }

}

        printf函数使用的是哪个串口可以在实际运行后使用串口助手看到,只有一个串口输出了两句信息。或者打开这个文件直接修改printf函数的串口,默认是COM1(也就是USART1 ---PA4 PA5),我们这里修改成USART0(PA2 PA3),然后printf函数就不用数据线输出了,要接转串口效果见图二。如果你依旧接数据线观察输出的话就会发现只剩一条信息了,因为板子上的数据线默认是接在串口1(USART1),效果见图三。

图二(注意这里是CH340转串口)

图二接线

 图三(注意这里是串行设备口)

 图三接线

百度云链接,建议使用精修改文件当模板,里面还有官网的整个HT32F52352的历程,但是比较晦涩难懂。

单个PWM只能有四路输出,如果4个不够的话,建议先在精修改文件里新建出两个PWM口,验证完再继续写其他内容。

点个赞,留个言再拿走吧!!!

链接:https://pan.baidu.com/s/17eMTxfDPCqiAtMJ7KlzQ4g 
提取码:yzyt

有关HT32F52352单片机,双串口,PWM的4路输出,GPIO输入(红外模块)(可以当合泰杯比赛的程序模板,非常好用),printf使用自定义串口输出的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  5. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  6. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  7. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  8. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  9. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  10. ruby - 如何进行排列以有效地定制输出 - 2

    这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][

随机推荐