#include <stdio.h>//函数指针类型别名/* * int 函数返回值 * (int,int)函数参数,两个参数int,int * *PTP_TO_FUNC函数指针,指向函数的指针*/typedef int (*PTR_TO_FUNC)(int, int);/* 为数组定义别名与函数指针类型别名类似 [4]数组各属 PTR_TO_ARR指向数组的名,其数组个数与参数个数相同 在使用是当成一种类型,在为其赋值时需要重新为其添加值*/typedef char(*PTR_TO_ARR)[10]; //实现函数体int max(int x, int y){ return x > y ? x : y;}int main(void){ //定义数组,等待指向 char str[3][10] = { "嘿嘿", "信息科技", "有限公司" }; // PTR_TO_ARR结构体指针,仍需要定义别名 PTR_TO_ARR arr = str[1]; // 指向函数 PTR_TO_FUNC func = max; printf("max(6,3): %d/n", (*func)(6, 3)); printf("str[1]: %s/n", (*arr)); //输出信息科技 return0;}
有限存贮容量的高速存贮部件 。寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需要n个触发器来构成。
基本寄存器 :只能并行送入数据,也只能并行输出。
移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入,并行输出,也可以串行输入,串行输出,还可以并行输入,串行输出或串行输入,并行输出,灵活,用途广泛。
在嵌入式编程中,常常需要对一些寄存器进行配置,有的情况下需要改变一1个字节中的某一位或者几位,但是又不想改变其它位原有的值,就可以使用按位运算符进行操作。
假如我们只需要设置第0位bit0的值为1时, 要保持其它位 不发生变化。
TEST = 0x01
此方式如果高7位没有使用,就不会有影响,但是如果高7位正在被使用,那么就会发生错误。
可以使用或运算:
TEST = TEST | 0x01;// 在实际中常用TEST |= 0x01;
给Test的低4位清 0 ,高四位保持不变:
TEST &= 0xF0; //使用十六进制
此方法在单片机中经常使用,先对需要设置的位用 &操作符进行清零操作,然后用 | 操作符设置值,改变GPIOA的状态,先对寄存器的值进行清零操作,然后根据需要设置的值进行 | 或运算:
GPIOA->CRL &= 0XFFFFFF0F; // 将第4~7位清零GPIOA->CRL &= 0X00000040; //设置相应的值,不改变其他位的值
GPIOx->BSRR = (((uint32_t)0x01) << pinpox); //将0x01 左移pinpox位,
通过左移而不是直接设置一个固定的值 :为了提高代码的可读性,直接就知道修改了第几位:
GPIOA->ODR |= 1<<5; //PA.5输出高,其它位不变
简单操作:
TIMx->SR = 0xFFF7; //此方法仍然影响可读性,
库函数:
TIMx -> SR = (uint16_t)~TIM_FLAG;
设置SR的第三位为 0 时即可设置为
TIMx->SR = (uint16_t)~TIM_FLAG_CC3;
#define TIM_FLAG_Update ((uint16_t)0x0001)#define TIM_FLAG_CC1 ((uint16_t)0x0002)#define TIM_FLAG_CC2 ((uint16_t)0x0004)#define TIM_FLAG_CC3 ((uint16_t)0x0008)#define TIM_FLAG_CC4 ((int16_t)0x0010)#define TIM_FLAG_COM ((uint16_t)0x0020)#define TIM_FLAG_Trigger ((uint16_t)0x0040)#define TIM_FLAG_Break ((uint16_t)0x0080)#define TIM_FLAG_CC1OF ((uint16_t)0x0200)#define TIM_FLAG_CC2OF ((uint16_t)0x0400)#define TIM_FLAG_CC3OF ((uint16_t)0x0800)#define TIM_FLAG_CC4OF ((uint16_t)0x1000)
位域:或称之为位段,英文表达式 Bit field 是一种数据结构,可以把数据以位元的形式紧凑的存储,并允许程序员对此结构进行位元进行操作。
优势:
位域可以分为两大类,一个是结构体位域,一个是共同体位域,由于共同体和结构体两者在定义上的形式都是相同的,从位域的定义形式上看,两者也基本都是相同的。
struct 位域结构体{ 类型说明符 位域名 : 长度;}结构体变量名;// 结构体位域struct example0{ unsignedchar x : 3; //冒号后面的证书指定了该位段所占用的位的数目。 unsignedchar y : 2; unsignedchar z : 1;}ex0_t;// 共同体位域union example1{ unsignedchar x : 3; unsignedchar y : 2; unsignedchar z : 1;}ex1_u;
位域大小原则 :整个结构体位域的总大小为最宽基本类型成员大小的整数倍。
位域基本都使用无符号类型。
不同的处理器,不同的编译器对位域的影响,位域虽然能够以位的形式操作数据,但是也被人们告知要慎重使用,原因在于不同的处理器结构,不同的编译器对于位域的一些特征会产生不同的结果。
处理器大端模式,小端模式的处理器也会对下面的结构体位域产生不一样的存储方式。
不同的编译器,结构体位域成员不同类型,不同的编译器对于位域会有不同的结果
当成员大小之和超过一个基本存储空间时,不同的编译器也会有不同的处理方式。
typedefunion{ unsignedchar Byte; struct { unsignedchar bit012 : 3; unsignedchar bit34 : 2; unsignedchar bit5 : 1; unsignedchar bit6 : 1; unsignedchar bit7 : 1; }bits;}registerType;
存储0x0000 8000定义一个指针指向地址:
registerType *pReg = (register*)0x00008000;// 使用位域寄存器进行赋值pReg->bits.bit5 = 1;pReg->bits.bit012 = 7;
本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-10474-0.htmlC语言操作寄存器和函数指针
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com