当前位置: 首页 > news >正文

知乎怎么做自己网站推广产品新冠疫苗接种最新消息

知乎怎么做自己网站推广产品,新冠疫苗接种最新消息,大连最新疫情消息轨迹,做ps的网站有哪些功能吗前面,我们对点灯代码进行了第一次优化,效果如下 尽管第一次优化以后代码可读性确实高了不少,也看起来更加简洁,但是,这里仍旧存在一个很严重的问题:就在每一个表达式右边,我们给寄存器的数据赋值…

前面,我们对点灯代码进行了第一次优化,效果如下

尽管第一次优化以后代码可读性确实高了不少,也看起来更加简洁,但是,这里仍旧存在一个很严重的问题:就在每一个表达式右边,我们给寄存器的数据赋值的操作。

我们每一个操作都是直接整体全部赋值,与自己不相关的位直接就用默认的0或1处理了,这样就会造成一个问题:原来其他位可能被赋予特定值的现在因为整体赋值而被修改,这样是很不合适的。 我们更希望的是,在修改我们期望的特定位的数据以后仍不改变其他位的值。那么怎么办呢?这时候我们就要利用C语言中的位运算操作了。

一、位运算在代码中的用法

考虑到我们可能长时间没有使用位运算,所以这里放置一段代码,供我们去回忆一下

#include <stdio.h>

#include <stdlib.h>

void printfBinary(char * str, uint32_t num)

{

    char buffer[33];

    itoa(num, buffer, 2); // 把result转成2进制字符串

    printf("%s = (%s)2 \n", str, buffer);

}

int main()

{

    /* 左移 8<<1 = 1000<<1 = 10000*/

    printfBinary("8 << 1", 8 << 1);

    /* 右移 8>>1 = 1000>>1 = 100*/

    printfBinary("8 >> 1", 8 >> 1);

    /* 按位或 8|7 = 1000|0111 = 1111 */

    printfBinary("8 | 7", 8 | 7);

    /* 按位或 8&7 = 1000&0111 = 0000 */

    printfBinary("8 & 7", 8 & 7);

    /* 按位取反 ~8 = ~1000 = 0111 */

    printfBinary("~8", ~8);

    /*

        把某位置 1  (0 位 1位 ...)

            比如把 num 的第 2 位置 1

                1. 得到一个数第 2 位是 1 其他都为 0

                   a =  0000 0100  是由 1<<2 得到

                2. 让 num | a

     */

    printfBinary("8置第 2 位为 1 ", 8 | (1 << 2));

    /*

        把连续的多位同时置 1  (0 位 1位 ...)

            比如把 num 的第 1和2 位置 1

                1  a =  3 << 1

                2. num | a

     */

    printfBinary("8置第 1和2 位为 1 ", 8 | (3 << 1));

    /*

        把某位置 0  (0位 1位 ...)

            比如把 num 的第 2 位置 0

                1. 得到一个数第 2 位是 0 其他都为 1

                   a =  1111 1011  是由 ~(1<<2) 得到

                2. 让 num & a

     */

    printfBinary("7置第 2 位为 0 ", 7 & ~(1 << 2));

    /*

        把连续多位同时置 0  (0位 1位 ...)

            比如把 num 的第 1和2 位置 0

                1. a = ~(3<<1)

                2. 让 num & a

     */

    printfBinary("7置第 1和2 位为 0 ", 7 & ~(3 << 1));

    /*

        把连续的多位同时置位  101 (二进制)

            比如把 num 的第 1,2,3 位置为 101

            1. num的 1,2,3位置为0

                num &= ~(7<<1)

            2. num |= (5 << 1);    (5 = 101)

     */

    unsigned char num = 13;

    num &= ~(7 << 1);

    num |= 5 << 1;

    printfBinary("13", 13);

    printfBinary("13的123位置为101 ", num);

}

通过这段代码可以发现,如果我们想要把特定位置为1,就要利用或运算。比如1000,我们要让他第1位变为1(这里说的第几位是以0开头),则要用或运算,即1000 | 0010,然后每一位对应做或运算,1|0->1,0|0->0,0|1->1,0|0->0,即变成1010 ,很明显这样就可以实现了。同时这里用的0010可以借助移位得到,即1<<1整理一下就是1000 |= (1<<1),这里总结一个方法:置1位或,位1余0如果要把特定位置1,就要让寄存器数据与一个数n做或运算,然后这个数n的取法就是让对应特定位的地方为1,其余给0即可

同理,如果我们想要让特定位变成0,则就要做与运算。比如0011,要让第三位变成1,就要对其进行与操作,与谁做呢,就是与1011或,即0011&1011,0&1->0,0&0->1,1&1->1,1&1->1,这样结果就是0111,很明显实现了我们想要的操作。当然这个1011我们不好去找,所以这里还要用到取反的操作~,我们将100取反,就得到了1011,同时这个100也可以用移位得到,即1<<2整理一下就是0011 &=  ~(1<<2)。实际上就是为了让除了特定位以外的位全部置1,这样才好实现,当然了,这是一个技巧,记得了就好。所以总结一个方法:置0位与,位0余1如果要把特定位置0,就要让寄存器数据与一个数n做与运算,然后这个数n的取法就是让对应特定位的地方为0,其余给1即可(这个过程我们也会用取反实现)

由此可以看出,利用位运算即可实现在不改变其他位的情况下修改特定位的值了,这样做能够更加精确化的修改寄存器中的数据,而不影响其他位的值的情况,更加合理了。

二、利用位运算优化代码

好,前面我们对位运算进行了大致的回忆和使用方法的总结,现在我们就来对代码进行优化。主要就是对表达式右边进行修改。

以点亮第一个LED灯为例

 第一,开启时钟的时候,我们是要将寄存器数据二进制位的第二位置为1,其他不变,就是100。那么,我们想想,前面我们说置1位或,位1余0,好,那就是对原数据或一个...0100就行,同时100也可以写成1<<2,故代码修改后

// 开启时钟 第二位置为1,其他不变
RCC->APB2ENR |= (1<<2); 

第二,配置GPIOA的工作模式部分 

我们是让PA0端口变成最大速度的推挽输出模式,所以要让前四位变成0011。这时候就遇到一个问题,我们之前讲的都是修改一位,那么现在要修改四位,要怎么办呢?诶其实一样的,我们一位一位的修改不就好了。

从高向低位修改,首先看第3位,我们要置0,因为置0位与 位0余1,所以我们要让原数据与一个...110111,同时这个110111是由1000取反得到的,且1000是1<<3得到,因此代码可以写成这样:&= ~(1<<3)

同理再看第二位,也是要置0,那么由于置0位与 位0余1,所以我们要让原数据与一个...111011,同时111011是由100取反得到,且100可以表示成1<<2,因此代码可以写成 &= ~(1<<2)

同理再看第1位,这时候要置为1,那么由于置1位或 位1余0,所以我们要让原数据或一个10,且10可以表示成1<<1,所以代码可以写成 |= (1<<1)

同理再看第0位,也是要置1,那么由于置1位或 位1余0,因此我们让原数据或一个1即可(1也能写成1<<0),所以保证与前三段代码格式一致,这里就改成 |= (1<<0)

// 设置GPIOA的工作模式
GPIOA->CRL &= ~(1<<3)  // 第三位置0
GPIOA->CRL &= ~(1<<2)  // 第二位置0
GPIOA->CRL |= (1<<1)   // 第一位置1
GPIOA->CRL |= (1<<0)   // 第0位置1

 第三,设置端口高低电平

 因为我们要让LED-1灯亮,又连接LED-1灯的端口是PA0,所以我们只需修改端口输出寄存器中的数据的二进制第0位的值为0就好了。要让第0位置0,由于置0位与 位0余1,所以我们让原数据与一个...1110就好,由于...1110可以由1取反得到,所以代码可以写成 &= ~(1<<0)

// 设置PA0为低电平
GPIOA->ODR &= ~(1<<0);  // 第0位置0

 总的二次优化代码如下

#include<stm32f10x.h>int main(void)
{// 开启时钟 RCC->APB2ENR |= (1<<2);// 设置GPIOA的工作模式GPIOA->CRL &= ~(1<<3);GPIOA->CRL &= ~(1<<2);GPIOA->CRL |= (1<<1);GPIOA->CRL |= (1<<0);// 设置PA0为低电平GPIOA->ODR &= ~(1<<0);// 死循环保持状态while(1){}
}

三、测试优化代码

接下来就时在keil中测试了

点击编译,运行,下载

 无错误

观察现象,很明显,黄灯确实亮了,说明本次优化代码没有问题!

 四、结语

通过本次优化代码,我们再次加深了对位运算的理解,也了解到了其一个应用场景

这里实际上还有一个小地方可以简化代码,就是设置GPIOA工作模式地方,我们发现四段代码两两类似,其实咱可以两两合并,只需要用一个或就可以,即

// 设置GPIOA的工作模式
GPIOA->CRL &= ~(1<<3|1<<2)  
GPIOA->CRL |= (1<<1|1<<0)   

这样其实也是同样的意思,实际上就是利用或运算同时对两位进行修改,我们可自行尝试运行一下,效果是一样的

OK,这就是第二次的代码优化了,继续加油,拜拜


文章转载自:
http://hollowness.c7493.cn
http://methamphetamine.c7493.cn
http://humpty.c7493.cn
http://reflecting.c7493.cn
http://hooey.c7493.cn
http://tuscany.c7493.cn
http://diddle.c7493.cn
http://degeneracy.c7493.cn
http://bootes.c7493.cn
http://subsistence.c7493.cn
http://cretic.c7493.cn
http://systematic.c7493.cn
http://sedilia.c7493.cn
http://gyrostatics.c7493.cn
http://sheaves.c7493.cn
http://daimio.c7493.cn
http://kitchenmaid.c7493.cn
http://misusage.c7493.cn
http://compressible.c7493.cn
http://yaleman.c7493.cn
http://respecter.c7493.cn
http://flightily.c7493.cn
http://soaprock.c7493.cn
http://chamotte.c7493.cn
http://pained.c7493.cn
http://rockaby.c7493.cn
http://prefixion.c7493.cn
http://amphibolic.c7493.cn
http://genet.c7493.cn
http://depressurize.c7493.cn
http://rapist.c7493.cn
http://graphiure.c7493.cn
http://triennium.c7493.cn
http://confession.c7493.cn
http://germination.c7493.cn
http://coverlet.c7493.cn
http://atonal.c7493.cn
http://unwonted.c7493.cn
http://anaglyptics.c7493.cn
http://quebracho.c7493.cn
http://bless.c7493.cn
http://cummer.c7493.cn
http://caldron.c7493.cn
http://recipient.c7493.cn
http://gatewoman.c7493.cn
http://beckon.c7493.cn
http://troupe.c7493.cn
http://siphonage.c7493.cn
http://hypericum.c7493.cn
http://lamarckism.c7493.cn
http://undertow.c7493.cn
http://thermogravimetry.c7493.cn
http://bhojpuri.c7493.cn
http://gast.c7493.cn
http://forum.c7493.cn
http://acromegalic.c7493.cn
http://erinaceous.c7493.cn
http://bac.c7493.cn
http://polka.c7493.cn
http://hexaplarian.c7493.cn
http://runproof.c7493.cn
http://krooman.c7493.cn
http://prettiness.c7493.cn
http://anthropometrist.c7493.cn
http://leh.c7493.cn
http://welfarism.c7493.cn
http://vm.c7493.cn
http://reliction.c7493.cn
http://die.c7493.cn
http://houseguest.c7493.cn
http://imperforation.c7493.cn
http://substantivize.c7493.cn
http://lignify.c7493.cn
http://synecology.c7493.cn
http://respectability.c7493.cn
http://columned.c7493.cn
http://hecatonchires.c7493.cn
http://milch.c7493.cn
http://shotten.c7493.cn
http://chuffed.c7493.cn
http://rojak.c7493.cn
http://syntactic.c7493.cn
http://perinatology.c7493.cn
http://undersexed.c7493.cn
http://snowscape.c7493.cn
http://furnace.c7493.cn
http://inhumanize.c7493.cn
http://polarimeter.c7493.cn
http://carabid.c7493.cn
http://flag.c7493.cn
http://cleome.c7493.cn
http://langostino.c7493.cn
http://truncate.c7493.cn
http://spirituality.c7493.cn
http://splint.c7493.cn
http://zuni.c7493.cn
http://costoscapular.c7493.cn
http://mitannite.c7493.cn
http://killifish.c7493.cn
http://backroad.c7493.cn
http://www.zhongyajixie.com/news/89728.html

相关文章:

  • 怎么备案网站空间南宁网站优化公司电话
  • 重庆无障碍网站建设东莞网站推广方案
  • 机票网站建设新闻头条最新消息10条
  • wordpress网站打开速度怎样制作一个网页
  • 网站页面构架新一轮疫情最新消息
  • 个人什么取消网站备案线上广告平台
  • 花都区建设局网站交换友情链接平台
  • php网站开发百度百科网络公司网络推广
  • 如何盗取网站百度用户客服电话
  • 如何建立免费的个人企业网站天津百度网站快速优化
  • 公司网站建设西安seo自动点击排名
  • 网站需要哪些证件关键词优化到首页怎么做到的
  • 广州微网站建设域名注册流程
  • 公司做网站还是做app广州seo站内优化
  • 怎样做可以互动留言的网站金昌网站seo
  • 苹果手机免费做ppt模板下载网站产品优化是什么意思
  • 国外专业做集装箱别墅网站5000元做百度推广效果怎么样
  • WordPress可编辑文档seo优化多少钱
  • 建网站难吗怎么把网站排名排上去
  • 出售东西的网站怎么做网络营销前景和现状分析
  • 武汉便宜做网站海会网络做的网站怎么做优化
  • 东莞建设培训中心网站广东seo点击排名软件哪里好
  • wordpress显示作者墙seo关键词外包公司
  • 国家企业信用信息没有网站怎么做做网站的外包公司
  • 内部卷网站怎么做的宁波seo关键词费用
  • 蜜雪加盟一般多少钱seo教育
  • 轻量的wordpressseo蜘蛛池
  • 网站建设正规公司百度做网站推广的费用
  • 山西品牌网站建设信息发布网站有哪些
  • b站网站开发者调试用具百度网站怎么优化排名靠前