串行通信 软件仿真STM32与74LS164通信

1、串行通信


2、常见的4种串行通信标准


3、对74LS164芯片的介绍

74LS164:串行转并行芯片,内部是1个8位的移位寄存器组成,由8个D触发器组成

缺点是:不带锁存寄存器,移位寄存器移位的过程会表现在164的输出引脚上,容易产生输出干扰。





4、用KEIL4进行软件仿真时,按正常步骤建立工程,然后在下图位置按照下图设置即可。


5、软件仿真:STM32与74LS164进行通信的程序如下:

/**************************************************************************************************
 *	硬件平台:STM32F103VC
 *	学习重点:GPIOx的位绑定
 *	实现功能:软件仿真,实现STM32与“串行转并行芯片164”进行通信
 *	164不带锁存器,给它串行传数据时,内部移位寄存器的移位过程会在其并行输出引脚上表现出来
 *	Clear引脚低电平有效,接STM32的PB.0引脚  Clock上升沿有效,接STM32的PA.1引脚
 *	A&B 相与后作为164的串行输入引脚
 **************************************************************************************************/

 /*=============================================================================
 * 位绑定公式:
 * 1、SRAM区域 :0X2200 0000 ----0X200F FFFF
 *    Aliasaddr = 0X22000000 + ( A -0X20000000 )*32 + n*4
 * 2、片上外设区域 :0X4200 0000 ----0X400F FFFF
 *    Aliasaddr = 0X42000000 + ( A -0X40000000 )*32 + n*4
 * 参数解释:
 *          Aliasaddr : 设置“端口GPIOx的第n位”的寄存器_相应位的实际地址
 *          A : 端口GPIOx的基地址(GPIOx_BASE) + 相应寄存器的偏移地址
 *          n : 配置的是相应寄存器的第n位
 * 寄存器的偏移地址 :CRL  CRH  IDR  ODR  BSRR  BRR  LCKR
 *                    00H  04H  08H  0CH  10H   14H  18H 
 =============================================================================*/


/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"


/******************************快速位绑定**********************************************************/
/*----------------1、宏定义要操作的寄存器地址---------------------------------------------*/
 #define GPIOA_ODR (GPIOA_BASE + 0X0C)
 #define GPIOA_IDR (GPIOA_BASE + 0X08)

 #define GPIOB_ODR (GPIOB_BASE + 0X0C)
 #define GPIOB_IDR (GPIOB_BASE + 0X08)

 #define GPIOC_ODR (GPIOC_BASE + 0X0C)
 #define GPIOC_IDR (GPIOC_BASE + 0X08)

 #define GPIOD_ODR (GPIOD_BASE + 0X0C)
 #define GPIOD_IDR (GPIOD_BASE + 0X08)

 #define GPIOE_ODR (GPIOE_BASE + 0X0C)
 #define GPIOE_IDR (GPIOE_BASE + 0X08)

/*----------------2、获取端口GPIOx(A-E)的对应寄存器的某一操作位的位地址-------------------*/
// #define BitBand(Addr , BitNum) *( (volatile unsigned long *)(Addr & 0xf0000000) + 0x2000000 + ((Addr&0xfffff)*32) + (BitNum*4) ) 
// 因为 左移、右移 语句的执行速度比乘除法语句的运动速度快,所以将上述语句改成如下方式
 #define BitBand(Addr , BitNum) *( (volatile unsigned long *)( (Addr & 0xf0000000) + 0x2000000 + ((Addr&0xfffff)<<5) + (BitNum<<2) ) ) 
  
/*----------------3、宏定义函数,对固定的位绑定 进行功能封装------------------------------*/
 #define PAout(n) BitBand(GPIOA_ODR , n) 
 #define PAin(n) BitBand(GPIOA_IDR , n)

 #define PBout(n) BitBand(GPIOB_ODR , n) 
 #define PBin(n) BitBand(GPIOB_IDR , n)

 #define PCout(n) BitBand(GPIOC_ODR , n) 
 #define PCin(n) BitBand(GPIOC_IDR , n)

 #define PDout(n) BitBand(GPIOD_ODR , n) 
 #define PDin(n) BitBand(GPIOD_IDR , n)

 #define PEout(n) BitBand(GPIOE_ODR , n) 
 #define PEin(n) BitBand(GPIOE_IDR , n)


/*----------------函数声明部分---------------*/
void delay1ms(int t) ;


/* Private functions -----------------------------------------------------------------------------*/ 
/**************************************************************************************************
* Function Name  : main
* Description    : 从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出
* Input          : None
* Output         : None
* Return         : None
****************************************************************************************************/
int main(void)
{
	u8 i , data ;

	/*--------控制STM32引脚GPIOA.0 GPIOA.1 GPIOB.0推挽输出高电平--------*/
	//1、设置GPIOA.0--A&B  GPIOA.1--CLOCK  GPIOB.0--CLEAR
		//GPIOA.0 GPIOA.1 GPIOB.0推挽输出,速度50MHZ 
		GPIOA->CRL = 0x33 ; // CNF0 = 00 MODE0 = 11
		GPIOB->CRL = 0x03 ; // CNF0 = 00 MODE0 = 11
		//GPIOA->CRH = 0x44444444 ; // CNF0 = 01 MODE0 = 00

	//2、与164进行通信,QA--QH : 01100101 ,PA0串行输出,PA1上升沿有效,PB0=0清零 =1传数据
		data = 0x65 ;
		//初次使用164,先对其进行清零 CLOCK = 0 然后 CLOCK = 1 , PA1 ——> CLOCK 先置为低电平,为缠上上升沿做准备
		PBout(0) = 0 ; 	
		PAout(1) = 0 ;
		PBout(0) = 1 ;
		//向164串行传送8位数据
		for(i = 0 ; i < 8 ; i++)
		{
			PAout(1) = 0 ;
			delay1ms(1) ; //CLOCK的低电平维持1ms
			if((data&0x01) == 0x01)
			{
				PAout(0) = 1 ; 
			}
			else
			{
				PAout(0) = 0 ; 
			}		
			PAout(1) = 1 ;
			delay1ms(1) ;//CLOCK的高电平维持1ms

			data = data >> 1 ;
		}

//	  	while(1)
//	  	{
//			;	
//	  	}
//
//		return 1 ;
}


void delay1ms(int t)
{
	//机器周期T = 1/(72000000/12)s = 1/6000000 s = 1/6 us
	int temp = 6000/4 ;
	while(t--)
	{
		while(temp--)
		{ ; }	
	}

}


6、软件仿真结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值