IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F103ZET6+ADF4351+HMI串口屏 -> 正文阅读

[嵌入式]STM32F103ZET6+ADF4351+HMI串口屏

STM32F103ZET6+ADF4351+HMI串口屏

功能:

  • 显示当前输出频率

  • 100KHz步进,通过HMI屏幕触控修改

  • 1MHz步进,通过HMI屏幕触控修改

  • 实时修改输出频率,通过HMI屏幕触控修改

人机界面:

人机界面是通过陶晶驰串口屏来实现的,串口屏和单片机通过串口通信,只需设定相同的波特率,就可以实现通信。

HMI可以通过USART HMI软件来写界面,非常的简单方便。

具体界面如下:

在这里插入图片描述

  • 输出频率:显示当前ADF4351输出频率
  • 频率步进:如图所示,支持100KHz,1MHz的频率步进
  • 频率校准:点击输入框,唤出数字键盘后,输入目标频率,点击OK, 按下校准键,修改成功,如下图:

STM32F103ZET6程序实现:

程序逻辑:

在这里插入图片描述

核心代码:

ADF4351.C

#include "ADF4351.h"
#include "delay.h"

//定义32位数据,每一个数字4位,要有8个数字
//这里的数字已经是配置好的了,直接调用就可以写入寄存器里面

#define ADF4351_R0			((u32)0X2C8018)
#define ADF4351_R1			((u32)0X8029)
#define ADF4351_R2			((u32)0X10E42)
#define ADF4351_R3			((u32)0X4B3)
#define ADF4351_R4			((u32)0XEC803C)
#define ADF4351_R5			((u32)0X580005)

#define ADF4351_R1_Base	((u32)0X8001)
#define ADF4351_R4_Base	((u32)0X8C803C)
#define ADF4351_R4_ON	  ((u32)0X8C803C)
#define ADF4351_R4_OFF	((u32)0X8C883C)

#define ADF4351_RF_OFF	((u32)0XEC801C)

#define ADF4351_PD_ON		((u32)0X10E42)
#define ADF4351_PD_OFF	((u32)0X10E02)


void ADF_Output_GPIOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
}

void ADF_Input_GPIOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_10|GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ; 
	GPIO_Init(GPIOB, &GPIO_InitStruct);	
}

void delay (int length)
{
	while (length >0)
	{
    	length--;
	}
}

void WriteToADF4351(u8 count, u8 *buf)
{
	u8 ValueToWrite = 0;
	u8 i = 0;
	u8 j = 0;
	
//	ADF_Output_GPIOInit();  
	
	ADF4351_CE = 1;
	delay_us(1);
	ADF4351_CLK = 0;
	ADF4351_LE = 0;
	delay_us(1);
	
	for(i = count; i>0; i--)
	{
		ValueToWrite = *(buf + i - 1);
		for(j = 0; j < 8; j++)
		{
			if(0x80 == (ValueToWrite & 0x80))
			{
				ADF4351_OUTPUT_DATA = 1;
			}
			else
			{
				ADF4351_OUTPUT_DATA = 0;
			}
			delay_us(1);
			ADF4351_CLK = 1;
			delay_us(1);
			ValueToWrite <<= 1;
			ADF4351_CLK = 0;	
		}
	}
	ADF4351_OUTPUT_DATA = 0;
	delay_us(1);
	ADF4351_LE = 1;
	delay_us(1);
	ADF4351_LE = 0;
}


void ReadToADF4351(u8 count, u8 *buf)
{
	u8 i = 0;
	u8 j = 0;
	u8 iTemp = 0;
	u8 RotateData = 0;
	
	ADF_Input_GPIOInit();
	ADF4351_CE = 1;
	delay_us(1);
	ADF4351_CLK = 0;
	ADF4351_LE = 0;
	delay_us(1);
	
	for(i = count; i > 0; i--)
	{
		for(j = 0; j < 8; j++)
		{
			RotateData <<= 1;
			delay_us(1);
			iTemp = ADF4351_INPUT_DATA;
			ADF4351_CLK = 1;
			if(0x01 == (iTemp & 0x01))
			{
				RotateData |= 1;
			}
			delay_us(1);
			ADF4351_CLK = 0;
		}
		*(buf+i-1) = RotateData;
	}
	delay_us(1);
	ADF4351_LE = 1;
	delay_us(1);
	ADF4351_LE = 0;
}


void ADF4351Init(void)
{
	u8 buf[4] = {0,0,0,0};
	
	ADF_Output_GPIOInit();
	
	buf[3] = 0x00;
	buf[2] = 0x58;
	buf[1] = 0x00;				//write communication register 0x00580005 to control the progress 
 	buf[0] = 0x05;				//to write Register 5 to set digital lock detector
	WriteToADF4351(4,buf);		//每次写入8位数据,共32位数据写入,因为每个寄存器有32位,每次控制一个寄存器

	buf[3] = 0x00;
	buf[2] = 0xec;				//(DB23=1)The signal is taken from the VCO directly;(DB22-20:4H)the RF divider is 16;(DB19-12:50H)R is 80
	buf[1] = 0x80;				//(DB11=0)VCO powerd up;
 	buf[0] = 0x3C;				//(DB5=1)RF output is enabled;(DB4-3=3H)Output power level is 5
	WriteToADF4351(4,buf);		

	buf[3] = 0x00;
	buf[2] = 0x00;
	buf[1] = 0x04;				//(DB14-3:96H)clock divider value is 150.
 	buf[0] = 0xB3;
	WriteToADF4351(4,buf);	

	buf[3] = 0x00;
	buf[2] = 0x01;				//(DB6=1)set PD polarity is positive;(DB7=1)LDP is 6nS;
	buf[1] = 0x0E;				//(DB8=0)enable fractional-N digital lock detect;
 	buf[0] = 0x42;				//(DB12-9:7H)set Icp 2.50 mA;
	WriteToADF4351(4,buf);		//(DB23-14:1H)R counter is 1

	buf[3] = 0x00;
	buf[2] = 0x00;
	buf[1] = 0x80;			   //(DB14-3:6H)MOD counter is 6;
 	buf[0] = 0x29;			   //(DB26-15:6H)PHASE word is 1,neither the phase resync 
	WriteToADF4351(4,buf); //nor the spurious optimization functions are being used
												 //(DB27=1)prescaler value is 8/9

	buf[3] = 0x00;
	buf[2] = 0x2c;
	buf[1] = 0x80;
 	buf[0] = 0x18;						//(DB14-3:0H)FRAC value is 0;
	WriteToADF4351(4,buf);		//(DB30-15:140H)INT value is 320;
}

void WriteOneRegToADF4351(u32 Regster)
{
	u8 buf[4] = {0,0,0,0};
	buf[3] = (u8)((Regster>>24)&(0X000000FF));
	buf[2] = (u8)((Regster>>16)&(0X000000FF));
	buf[1] = (u8)((Regster>>8) &(0X000000FF));
	buf[0] = (u8)((Regster)&(0X000000FF));
	WriteToADF4351(4, buf);	
}

void ADF4351_Init_some(void)
{
	WriteOneRegToADF4351(ADF4351_R2);
	WriteOneRegToADF4351(ADF4351_R3);
	WriteOneRegToADF4351(ADF4351_R5);
}

void ADF4351WriteFreq(float Fre) //写入频率
{
	u16 Fre_temp, N_Mul = 1, Mul_Core = 0;
	u16 INT_Fre, Frac_temp, Mod_temp, i;
	u32 W_ADF4351_R0 = 0, W_ADF4351_R1 = 0, W_ADF4351_R4 = 0;
	float multiple;
	
	if(Fre < 35.0) //频率限幅
	{
		Fre = 35.0;
	}
	if(Fre > 4400.0)
	{
		Fre = 4400.0;
	}
	
	Mod_temp = 1000;
	Fre = ((float)((u32)(Fre * 10))) / 10;
	Fre_temp = Fre;
	
	for(i = 0; i < 10; i++)
	{
		if(((Fre_temp * N_Mul) >= 2199.9) && ((Fre_temp * N_Mul) <= 4400.1))
		{
			break;
		}
		Mul_Core++;
		N_Mul = N_Mul * 2;
	}
	
	multiple = (Fre * N_Mul) / 25;		//带宽出已固定为参考25M,若改参考频率,则应修改R4低字节  原本25 修改频率
	INT_Fre = (u16)multiple;
	Frac_temp = ((u32)(multiple * 1000)) % 1000;
	
	while(((Frac_temp % 5) == 0) && ((Mod_temp % 5) == 0))
	{
		Frac_temp = Frac_temp / 5;
		Mod_temp = Mod_temp / 5;
	}
	while(((Frac_temp % 2) == 0) && ((Mod_temp % 2) == 0))
	{
		Frac_temp = Frac_temp / 2;
		Mod_temp = Mod_temp / 2;
	}
	
	Mul_Core %= 7;
	W_ADF4351_R0 = (INT_Fre << 15) + (Frac_temp << 3);
	W_ADF4351_R1 = ADF4351_R1_Base + (Mod_temp << 3);
	W_ADF4351_R4 = ADF4351_R4_ON + (Mul_Core << 20);
	
	WriteOneRegToADF4351(ADF4351_RF_OFF);
	WriteOneRegToADF4351(W_ADF4351_R1);
	WriteOneRegToADF4351(W_ADF4351_R0);
	WriteOneRegToADF4351(W_ADF4351_R4);
}

ADF4351.H

#ifndef _ADF4351_H_
#define _ADF4351_H_

#include "sys.h"

#define ADF4351_CLK PBout(8)
#define ADF4351_OUTPUT_DATA PBout(9)
#define ADF4351_LE PBout(10)
#define ADF4351_CE PBout(11)

#define ADF4351_INPUT_DATA PBin(9)


void ADF4351Init(void); 
void ReadToADF4351(u8 count, u8 *buf);
void WriteToADF4351(u8 count, u8 *buf);
void WriteOneRegToADF4351(u32 Regster);
void ADF4351_Init_some(void);
void ADF4351WriteFreq(float Fre);		//	(xxx.x) M Hz

#endif

HMI.C

#include "HMI.h"

uint16_t  trans = 0;
float fre_mhz = 300;	//adf4351输出300MHz	
char buf[64];

/*****串口屏通信函数*****/

void HMI_choose(unsigned char ch)
{
	char  temp[4];
	int i = 0;
    switch (ch)
    {
			case 0x01:
					LED0 = 0;
					fre_mhz += 0.1;	
					ADF4351WriteFreq(fre_mhz);
			  	sprintf(buf,"x0.val=%.0f",fre_mhz*10);
					HMISends(buf);
					HMISendb(0xff);
					break;
			case 0x02:
					LED1 = 0;
					fre_mhz -= 0.1;
					ADF4351WriteFreq(fre_mhz);
					sprintf(buf,"x0.val=%.0f",fre_mhz*10);
					HMISends(buf);
					HMISendb(0xff);			
					break;
			case 0x03:
					LED0 = 1;
					fre_mhz += 1;
					ADF4351WriteFreq(fre_mhz);
					sprintf(buf,"x0.val=%.0f",fre_mhz*10);
					HMISends(buf);
					HMISendb(0xff);
					break;
			case 0x04:
					LED1 = 1;
					fre_mhz -= 1;
					ADF4351WriteFreq(fre_mhz);
					sprintf(buf,"x0.val=%.0f",fre_mhz*10);
					HMISends(buf);
					HMISendb(0xff);
					break;
			case 0x05:
					temp[0] = USART_RX_BUF[1];
					temp[1] = USART_RX_BUF[2];
					temp[2] = USART_RX_BUF[3];
					temp[3] = USART_RX_BUF[5]; //USART_RX_BUF[4]是小数点0x2e,我们跳过
					
					fre_mhz = 0;			//清零之前设定的频率,防止数据叠加
					for ( i = 0; i < 4; i++)
					{
						fre_mhz = fre_mhz *10 + temp[i] - '0';	// 通过减去'0'可以将字符转换为int类型的数值
					}					
					fre_mhz = fre_mhz * 0.1;
					ADF4351WriteFreq(fre_mhz);
					sprintf(buf,"x0.val=%.0f",fre_mhz*10);
					HMISends(buf);
					HMISendb(0xff);
					break;
			default :
					break;
    }
}

void HMIReceive(void)
{
    if(USART_RX_STA & 0x8000)
    {
        trans = USART_RX_BUF[0];
        HMI_choose(trans);
        USART_RX_STA = 0;
    }
}

void HMISends(char *buf1)		  //字符串发送函数
{
    u8 i = 0;
    while(1)
    {		
        if(buf1[i] != 0)
        {
            USART_SendData(USART1, buf1[i]); //发送一个字节
            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {}; //等待发送结束
            i++;
        }
        else
            return ;

    }
}

void HMISendb(u8 k)		         //字节发送函数
{
    u8 i;
    for(i = 0; i < 3; i++)
    {
        if(k != 0)
        {
            USART_SendData(USART1, k); //发送一个字节
            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {}; //等待发送结束
        }
        else
            return ;
    }
}

HMI.H

#ifndef __HMI_H
#define __HMI_H	 
#include "stm32f10x.h"
#include "usart.h"
#include "LED.h"
#include "adf4351.h"

extern uint16_t  trans;
extern char buf[64];;
extern float fre_mhz;		
void HMISends(char *buf1);	 
void HMISendb(u8 k);		     
void HMI_choose(unsigned char ch);
void HMIReceive(void);


#endif

MAIN.C

#include "delay.h"
#include "sys.h"
#include "string.h"
#include "usart.h"
#include "ADF4351.h"
#include "HMI.h"
#include "LED.h"
#include "stm32f10x.h"

void ADF4351Init(void);	
void ReadToADF4351(u8 count, u8 *buf);
void WriteToADF4351(u8 count, u8 *buf);
void WriteOneRegToADF4351(u32 Regster);
void ADF4351WriteFreq(float Fre);			

int main(void)
{
   SystemInit();        //初始化RCC 设置系统主频为72MHZ
	 delay_init(72);	     //延时初始化
		uart_init(115200);
    ADF4351Init();				//ADF4351初始化函数
    ADF4351WriteFreq(fre_mhz);//ADF4351芯片写入频率
		LED_Init();
    while(1)
    {
			HMIReceive();
    }
}

硬件:

原理图

在这里插入图片描述

概述:

  • ADF4351结合外部环路滤波器和外部参考频率使用时,可实现小数N分频或整数N分频锁相环(PLL)频率合成器。

  • ADF4351具有一个集成电压控制振荡器(VCO), 其基波输 出频率范围为2200MHz至4400 MHz。

  • 此外,利用1/2/4/8/ 16/32/64分频电路,用户可以产生低至35 MHz的RF输出频 率。

  • 对于要求隔离的应用,RF输出级可以实现静音。静音 功能既可以通过引脚控制,也可以通过软件控制。

  • 同时提供辅助RF输出,且不用时可以关断。 所有片内寄存器均通过简单的三线式接口进行控制。

  • 该器件采用3.0 V至3.6 V电源供电,不用时可以关断。

连线

ADF4351STM32F103ZET6
CLKPB8
DATAPB9
LEPB10
CEPB11

实物图:

[外链图片转存中…(img-6PzCE3yv-1628251825760)]在这里插入图片描述
在这里插入图片描述
2222

工程源码已经上传,还在审核中。。。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:15:04  更:2021-08-07 12:15:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:20:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码