冯·诺依曼结构的处理器使用同一个存储器,即程序和数据共用同一个存储器;而哈佛结构则是程序和数据采用独立的总线来访问程序存储器和数据存储器。
AMBA 总线主要有系统总线和外围总线两类,系统总线连接高速部件,主要包括第一代系统总线 ASB、第二代 AHB、第三代 AX 及第四代 ACE 等,而外围总线连接低速部件。有 APB(即 APB1)、APB2、APB3 和 APB4 等。
系统总线的主要特点是高速,即其连接的所有部件均能以内核速度工作(高速),而外围总线通过连接的部件的速度均低于内核速度。
根据 AMBA 总线的特点,快速部件全部连接在系统总线上,可知,SDRAM,SRAM 以及高速GPIO 端口连接在系统总线上,而其它均连接在外围总线上如 I2C 总线接口,SPI 总线接口,UART 接口,普通 GPIO 端口以及 RTC 接口。
初始化端口:
GPIOD_CRL EQU 0x40011400
GPIOD_CRH EQU 0x40011404
GPIOD_IDR EQU 0x40011408
GPIOD_ODR EQU 0x4001140C
由电路图知,LED1~LED4 分别对应 PD2,PD3,PD4 和 PD7 为推挽输出,使用 50MHz,KEY1 和 KEY2 分别对应 PD11和 PD12 浮空输入
// 设置 PD2/3/4/7 为推挽输出 10MHz
LDR R0,=GPIOD_CRL
LDR R1,[R0]
LDR R2,=0x1FF111FF //0001 1111 1111 0001 0001 0001 1111 1111
ANDS R1,R1,R2
STR R1,[R0]
LDR R0,=GPIOD_CRH
LDR R1,[R0]
//
LDR R2,=0xFFF44FFF //确保 PD11 和 PD12 的配置 CNF=01
ANDS R1,R1,R2
LDR R2,=0x00044000 //确保 PD11 和 PD12 的 MOD=00
ORRS R1,R1,R2
STR R1,[R0]
MOV R2,#0
//
L0 LDR R0,=GPIOD_IDR
LDR R1,[R0]
LDR R2,=0x00000800
ANDS R1,R2
BEQ L1
LDR R2,=0x00001000
ANDS R1,R2
BEQ L2
L1 MOV R2,#1
B L3
L2 MOV R2,#2
L3 CMP R2,#1
BEQ LED13
CMP R2,#2
BEQ LED24
B LEDCOM
LED13 LDR R0,=GPIOD_ODR
LDR R1,[R0]
LDR R2,=0xFFFFFFEB //PD2,PD4=0
ANDS R1,R1,R2
LDR R2,=0x00000088 //PD3,PD7=1
ORRS R1,R1,R2
STR R1,[R0] //LED1,LED3 亮,LED2,LED4 灭
B LEDCOM
LED24 LDR R0,=GPIOD_ODR
LDR R1,[R0]
LDR R2,=0xFFFFFF77 //PD3,PD7=0
ANDS R1,R1,R2
ORRS R1,R1,#0x14 //PD2,PD4=1
STR R1,[R0] //LED2,LED4 亮,LED1,LED3 灭
B LEDCOM
LEDCOM B L0
uint8_t KEY=0;
GPIOD->CRL&=~(0xE<<8)&~(0xE<<12)&~(0xE<<16);
GPIOD->CRL|=(4<<12)|((4<<16);
GPIOD->CRL&=~(0xB<<12)&~(0xB<<16);
While(1)
{
If(GPIOD->IDR&(1<<11)==0) KEY=1;
else If(GPIOD->IDR&(1<<12)==0) KEY=2;
switch(KEY)
{
case 1: GIOD->ODR&=~(1<<2)&~(1<<4);
GIOD->ODR|=(1<<3)|(1<<7);
break;
case 2: GIOD->ODR&=~(1<<3)&~(1<<7);
GIOD->ODR|=(1<<2)|(1<<4);
break;
}
}
#define KEY1 GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_11)
#define KEY2 GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_12)
uint8_t KEY=0;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIORCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 |GPIO_Pin_3 |GPIO_Pin_4 |GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
while(1)
{
If(KEY1==0) KEY=1;
else If(KEY2==0) KEY=2;
switch(KEY)
{
case 1: GPIO_ResetBits(GPIOD,GPIO_Pin_2|GPIO_Pin_4);
GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_7);
break;
case 2: GPIO_ResetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_7);
GPIO_SetBits(GPIOD,GPIO_Pin_2|GPIO_Pin_4);
break;
}
}
答:信号滤波主要的类型有:高通滤波器、低通滤波器、带通滤波器和带阻滤波器等。
主要特点:
高通滤波器指只能通过高频,中低频被阻止通过;
低通滤波是指只能通过低频,中高频率的信号被阻止,
带阻滤波器是仅允许高低频通过,中间频率段被阻止。
void ADC_Configuration(void) //配置和初始化 ADC
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|
RCC_APB2Periph_ADC1,ENABLE);//A口及A口多功能时钟选择(PA3为ADCIN3)
/* 配置GPIO的PA7作为ADCIN3模拟通道输入端,频率50MHz */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_GPIO_Pin_3;//ADC1通道PA3=ADIN3引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO端口
/* 初始化ADC:独立模式、多通道扫描、连续转换、软件触发、ADC数据右对齐 */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立工作模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //开启多通道扫描
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;//进行规则转换的ADC通道数为1个通道
ADC_Init(ADC1, &ADC_InitStructure);
/* 设置ADC1使用ADCIN7转换通道,转换顺序1,采样时间为239.5周期*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_239Cycles5 );
ADC_Cmd(ADC1, ENABLE); //使能ADC1
ADC_ResetCalibration(ADC1); //使能ADC1复位校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准寄存器接收
ADC_StartCalibration(ADC1); //启动ADC1校准
while(ADC_GetCalibrationStatus(ADC1)); //等待ADC1校准结束
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //启动软件转换
}
可采用查询方式获取 ADC 的值,参考程序如下:
uint16_t Temp;
float Valtage;//电压值
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
Temp = ADC_GetConversionValue(ADC1); //调用库函数获取转换值
假设在由电位器电位可知,当V=0V
时,测算的数字量为N0=0,V=3.3V=3300mV
时测算的数字量为Nm=0xFFF
,则通过标度变换公式(7.2)得到任何数字对应的电压值为:
Yx=Y0+(Ym-Y0)*(Nx-N0)/(Nm-N0)=0+3300*Nx/0xFFF=3300Nx/0xFFF (mV)
,代码为:
Valtage=3300*Temp/0xFFF;//压力换算值,单位mV
利用 DAC 通过外接运放产生幅度可变,周期可编程的正弦波的基本方法是首先采集一个周期正弦波的平均 N 个点如 32 个点的幅值,保存在程序存储器中或数据存储器中,然后利用定时器定时,定时长度取决于正弦波的周期,如周期为 T,则定时时间间隔 t=T/(N-1),在定时中断服务程序中输出保存在存储器中正弦的瞬时幅值,设置好初值指针,每定时时间到输出一个点,指针加一,通过(N-1)次定时中断即可输出一个周期的正弦波,当指针回零时,继续定时中断即可输出连续的正弦波。由 DAC 输出特点可知,它是 12 位 DAC,因此输出电压 Vo= DAC 输出= VREFx (DOR / 4095)
,在
参考电压一定的情况下,输出大小取决于数字量,将公式变换为:
Vo=K*Dx/4095
,Dx 为保存在存储器中的要输出的正弦波的点的值,K 已经考虑了参考电压,运放放大倍数等因素,因此要控制正弦波幅值只需要在程序中改变 K 的大小,而要改变正弦波的周期,只需要改变定时时间间隔。
对于 STM32F10x 的 DAC 可进行如下配置:
DAC 初始化包括 GPIO 引脚初始化为 DAC 引脚和 DAC 相应配置。
GIO 初始化包括使能对应 DAC 通道的 GPIO 引脚时钟,使能 DAC 时钟,设置通道引脚为模拟输入。一旦使能 DACx 通道,相应的 GPIO 引脚(通道 1 的 PA4 或者通道 2 的 PA5)就会自动与 DAC 的模拟输出相连(DAC_OUT1 或 DAC_OUT2)。为了避免寄生的干扰和额外的功耗,引脚 PA4 或者 PA5 在之前应当设置成模拟输入(AIN)。
DAC 初始化包括选择触发方式、是否使用波形发生、关闭输出缓冲、使能 DAC、通道 1 或 2 由软件触发。
设置通道 12 位右对齐模式。
具体初始化及配置程序如下:
void DAC_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC ,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_AFIO,ENABLE);
/*-----------DAC 端口配置 PA4/PA5 DAC1 通道 4 模拟输入-------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA ,&GPIO_InitStructure);
DAC_DeInit(); //还原到初始状态
/* DAC 通道 1 配置 */
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T3_TRGO; //T3 触发
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //不用波形产生
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //失能输出缓冲
DAC_Init(DAC_Channel_1, &DAC_InitStructure); //DAC 初始化
DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1 自动连接至 PA4
DAC_SetChannel1Data(DAC_Align_12b_R,0);//通道 1 右对齐输出
}
答:主要有三种任务结构:
(1)单次执行的任务:单次任务在系统运行时仅执行一次,比如系统初始化任务。
(2)周期执行的任务:周期性执行是每隔指定时间就要执行的任务,比如数据采集与处理等任务。
(3)事件触发执行的任务:事件触发执行,只有事件触发时才去执行该任务,如外部中断触发任务。