s7200系列可编程序控制器中读取内部时钟,用什么指令

s7200系列可编程序控制器中读取内部时钟,用什么指令,第1张

s7200系列可编程序控制器中读取内部时钟,用readrtc和setrtc指令。根据查询相关资料信息显示,读取实时时钟指令从硬件时钟读取当前时间和日期,并将其载入以地址T起始的8个字节的时间缓冲区。

#include<at89x52h>

#include<intrinsh>

//include"iicc"

#define uint unsigned int

#define uCHAR unsigned CHAR

sbit SDA=P3^1;

sbit SCL=P3^0;

uCHAR code shu1[]={0xfd,0x61,0xbb,0xeb,0x67,0xcf,0xdf,0xe1,0xff,0xef,0xa7,0xf5,0x97,0x03};

uCHAR data dingshi[]={0x00,0x03,0x00,0x02};

uCHAR data xian[]={0x00,0x00,0x00,0x00};

uCHAR k[]={0x00};

uCHAR a1=0x00,a3=0;

bit a2;

uCHAR idata rd[3]={0x01,0xa0,0xa1};

uCHAR idata wr[3]={0x01,0xa0,0xa1};

uCHAR TEMP[5]={0x00,0x00,0x00,0x00,0x00};

uCHAR n=0;

void delay(uint x);

void sta();

void stop();

void mack();

void mnack();

void cack();

void wrbyt(uCHAR shu);

void wrbyt0();

void wrbyt1();

uCHAR rdbyt();

void wrnbyt(uCHAR slaw,uCHAR NUMBER,uCHAR ff[]);

void rdnbyt(uCHAR NUMBER,uCHAR slar,uCHAR qq[]);

void wrnbyta(uCHAR slaw,uCHAR gg[],uCHAR n);

void xianshi();

void miaojian();

uCHAR panjian();

void fenjia();

void jianchuli();

uCHAR panjian()

{

P3_2=1;

P3_0=1;

if(P3_2==0)

{

n=n+1;

return 1;

}

else

{

P3_2=1;

P3_0=0;

if(P3_2==0)

{

P3_0=1;

return 2;

}

}

}

void fenjia()

{

uCHAR a8[]={0x00,0x00};

if(n==1)

{

a8[0]=dingshi[0];

a8[1]=dingshi[1];

}

else if(n==2)

{

a8[0]=dingshi[2];

a8[1]=dingshi[3];

}

if(a8[1]<9)

{

a8[1]=a8[1]+1;

}

else

{

if(a8[0]<9)

{

a8[0]=a8[0]+1;

a8[1]=0x00;

}

else

{

a8[1]=0x00;

a8[0]=0x00;

}

}

if(n==1)

{

dingshi[0]=a8[0];

dingshi[1]=a8[1];

}

else if(n==2)

{

dingshi[2]=a8[0];

dingshi[3]=a8[1];

}

}

void jianchuli()

{

uCHAR jk;

n=1;

while(n<3)

{

if(n==1)

{

xian[0]=0;

xian[1]=0x0b;

xian[2]=dingshi[0];

xian[3]=dingshi[1];

}

else if(n==2)

{

xian[0]=0;

xian[1]=0x0b;

xian[2]=dingshi[2];

xian[3]=dingshi[3];

}

for(jk=0;jk<100;jk++)

{

xianshi();

}

jk=panjian();

if(jk==1)

{

n=n+1;

}

else if(jk==2)

{

fenjia();

}

}

}

void sta()

{

SDA=1;

SCL=1;

while(SCL==0)

{

;

}

_nop_();

SDA=0;

_nop_();

_nop_();

SCL=0;

}

void stop()

{

SDA=0;

SCL=1;

while(SCL==0)

{

;

}

_nop_();

SDA=1;

_nop_();

_nop_();

SCL=0;

}

void mack()

{

SDA=0;

SCL=1;

_nop_();

_nop_();

SCL=0;

SDA=1;

}

void mnack()

{

SDA=1;

SCL=1;

_nop_();

_nop_();

SCL=0;

SDA=0;

}

void cack()

{

SDA=1;

SCL=1;

F0=0;

if(SDA==0)

{

SCL=0;

_nop_();

_nop_();

}

else

{

F0=1;

SCL=0;

_nop_();

_nop_();

}

}

void wrbyt(uCHAR shu)

{

uCHAR i;

if((shu&0x80)>0)

{

SDA=1;

}

else

{

SDA=0;

}

SCL=1;

while(SCL==0)

{;}

_nop_();

SCL=0;

SDA=0;

shu=_crol_(shu,1);

for(i=1;1<8;i++)

{if((shu&0x80)>0)

{wrbyt1();}

else

{wrbyt0();}

shu=_crol_(shu,1);

}

}

void int00() interrupt 0

{

uCHAR m,k;

uCHAR xian1[]={0x00,0x00,0x00,0x00};

TR0=0;

IE=0x00;

xianshi();

n=0;

P3_0=1;

P3_2=1;

m=panjian();

if(m==1)

{

for(k=0;k<4;k++)

{

xian1[k]=xian[k];

}

jianchuli();

TEMP[0]=0x01;

TEMP[1]=dingshi[0];

TEMP[2]=dingshi[1];

TEMP[3]=dingshi[2];

TEMP[4]=dingshi[3];

wrnbyt(0xa0,5,TEMP);

delay(300);

TEMP[0]=0x10;

TEMP[1]=0x01;

wrnbyt(0xa0,2,TEMP);

}

for(k=0;k<4;k++)

{

xian[k]=xian1[k];

}

P3_0=1;

P3_2=1;

IE=0x83;

TR0=1;

}

void wrbyt0()

{

SDA=0;

SCL=1;

_nop_();

_nop_();

SCL=0;

}

void wrbyt1()

{

SDA=1;

SCL=1;

_nop_();

_nop_();

SCL=0;

SDA=0;

}

uCHAR rdbyt()

{

uCHAR nn=0xff,mm=0x80,uu=0x7f;

uCHAR j;

uint q=0;

for(j=0;j<8;j++)

{

SDA=1;

SCL=1;

if(SDA==0)

{nn=(nn&uu);

nn=_crol_(nn,1);

SCL=0;

}

else

{

nn=(nn|mm);

nn=_crol_(nn,1);

SCL=0;

}

}

return(nn);

}

void wrnbyta(uCHAR slaw,uCHAR gg[],uCHAR n)

{

do{

sta();

wrbyt(slaw);

cack();

}while(F0==1);

wrbyt(gg[n]);

cack();

}

void wrnbyt(uCHAR slaw,uCHAR NUMBER,uCHAR ff[])

{

uCHAR idata k;

do{

sta();

wrbyt(slaw);

cack();

}while(F0==1);

for(k=0;k<NUMBER;k++)

{

wrbyt(ff[k]);

cack();

while(F0==1)

{

wrnbyta(slaw,ff,k);

}

}

stop();

}

void rdnbyt(NUMBER,slar,qq)

uCHAR NUMBER,slar,qq[];

{

uCHAR idata data0,l;

do{

sta();

wrbyt(slar);

cack();

}while(F0==1);

for(l=0;l<NUMBER;l++)

{

data0=rdbyt();

qq[l]=data0;

if(l<(NUMBER-1))

{mack();}

}

mnack();

stop();

}

void delay(uint x)

{

uCHAR j;

while(x--)

{

for(j=0;j<150;j++)

{;}

}

}

void main()

{

SP=0x60;

TCON=0x01;

IP=0x01;

TMOD=0x01;

TH0=0x3c;

TL0=0xb0;

IE=0x83;

wrnbyt(0xa0,1,0x10); // 读0x10地址一字节

rdnbyt(1,0xa1,k);

if(k[0]!=1)

{

TEMP[0]=0x01;

TEMP[1]=dingshi[0];

TEMP[2]=dingshi[1];

TEMP[3]=dingshi[2];

TEMP[4]=dingshi[3];

wrnbyt(0xa0,5,TEMP); //写TEMP数组(5字节)

delay(300);

}

wrnbyt(0xa0,1,0x01);

rdnbyt(4,0xa1,dingshi); //读0x01开始4字节

xian[0]=dingshi[0];

xian[1]=dingshi[1];

xian[2]=0x00;

xian[3]=0x00;

a2=0;

TR0=1;

while(1)

{

TR0=1;

P3_2=1;

xianshi();

P3_7=a2;

}

}

void xianshi()

{

uCHAR i=0x00;

for(i=0;i<4;i++)

{

P1=0x01;

P3_3=1;

P3_4=1;

P3_5=1;

P1_0=1;

P1=shu1[xian[i]];

SWITCH(i)

{

case 0:

{

P1_0=0;

}

break;

case 1:

{

P3_5=0;

}

break;

case 2:

{

P3_4=0;

}

break;

case 3:

rtc实时时钟一般功能比较强,自带万年历和闹铃功能,并且其工作电流只有几十微安,但必须配合单片机才能进行时间显示和设置

单片机也可以编程作为时钟,但是占用CPU开销大,且功耗大,不便于断电后用备用电池供电

因此,多数单片机控制系统都另加一片实时时钟芯片

当然,有些单片机内部集成了实时时钟功能,如STM32F407,但其晶振和供电包括寄存器区都和其它部分独立,便于用电池供电

西门子的READRTC指令可以使用于子程序,并且可以在子程序中引用RTC值作为数据处理的参考,但要注意的是,READRTC指令的执行时间需要在子程序的最后对实时时钟进行读取,以保证读取出来的RTC值能够正确。

一、读实时时钟时间

第一步:(在桌面打开STEP 7-MicroWIN SMART编程软件)

第二步:(用字节转整数+BCD码转整数指令来读取实时时钟时间(B_I—BCD_I))。

第三步:(读取实时时钟指令(READ_RTC))

二、写时钟时间

第一步:(用整数转BCD码+整数转字节来写入时钟设定时间(BCD_I—I_B))。

第二步:(设置实时时钟指令(SET_RTC))

第三步:(监控读取PLC实时时间,当时时间:2020年6月11日15:09星期四)

第四步:(监控写入PLC设定时间,设定时间: 2016年6月12日18:22分星期日)

第二步:(创建一个读取时间画面)

1 通过鼠标选中数字右击来新增基本画面并把窗口名称重新命名(读取时间)

2 设置数显、关联地址、设置标签文字、设置功能键切换窗口。

第三步:(创建一个写入时间画面)

1 通过鼠标选中数字右击来新增基本画面并把窗口名称重新命名(写入时间)

2 设置数显、关联地址、设置标签文字、设置功能键切换窗口。

三、在线模拟看一下效果

第一步:(点击启动读取按钮,现在读取PLC时间是:2020年10月12日星期一 10:01 04秒)

第二步:(先写入一个日期和时间,然后点击启动写入按钮,切换到读取时间窗口这时会看到时间已经写入成功并计时开始)

注意事项:在最后第八位表示星期的时候其中1 = 星期日,7 = 星期六,0 = 表示禁止计星期。

        读者们,大家好!

        接着上一章多功能时钟(绪论)的内容,在这一章中,我将介绍多功能时钟的时钟显示部分。话不多说,我们正式开始吧~

        多功能时钟,时钟显示功能是必不可少的。所以,我们利用stm32的定时器来计时。本来打算采用stm32的RTC实时时钟,但后来想,刚开始弄得时候,尽量简单一些,别一开始就给自己出难题,毕竟RTC实时时钟要配置的东西还挺多的。如果此次做得不错的话,后面可以再加RTC实时时钟。

        stm32不同于51,共有11个定时器,其中2个高级控制定时器(TIM1和TIM8),4个普通定时器(TIM2~TIM5)和2个基本定时器(TIM6和TIM7),以及2个看门狗定时器和1个系统滴答定时器。这里,我们采用普通定时器TIM2,并且开启定时器的中断,中断时间为1s,并且在中断函数里,模拟时钟的计时功能。

(1)配置嵌套中断控制器NVIC

void tim2_nvic_config(void)

{

    NVIC_InitTypeDef NVIC_InitStruct;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructNVIC_IRQChannel = TIM2_IRQn;

    NVIC_InitStructNVIC_IRQChannelPreemptionPriority = 2;//抢占优先级为2

    NVIC_InitStructNVIC_IRQChannelSubPriority = 0;//子优先级为0

    NVIC_InitStructNVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);

}

        这里,我们只需对NVIC_InitStruct结构体的每个元素赋值,其中TIM2_IRQn为定时器TIM2中断线,设置优先级组为2,即抢占优先级组为4组,这里抢占优先级为2,子优先级为0,然后使能NVIC(优先级不能理解上网查询)。

(2)定时器初始化配置

void tim2_config(void)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

    tim2_nvic_config();                                //配置NVIC

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启时钟

    TIM_DeInit(TIM2);                                      //定时器2复位

    TIM_TimeBaseInitStructTIM_Period = 2000-1;                  //自动重装载寄存器值

    TIM_TimeBaseInitStructTIM_Prescaler = 36000-1;              //时钟预分频数

    TIM_TimeBaseInitStructTIM_ClockDivision = TIM_CKD_DIV1;    //采样分频

    TIM_TimeBaseInitStructTIM_CounterMode = TIM_CounterMode_Up; //计数模式

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);            //初始化TIM2

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);                        //清除溢出中断标志

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM2, ENABLE);                                      //使能时钟

}

        TIM2初始化,首先配置NVIC,打开TIM2时钟,复位TIM2。然后对TIM_TimeBaseInitStruct结构体的每个元素赋值。这里,主要阐述如何计算定时中断时间。定时器的溢出中断时间由TIM_Period和TIM_Prescaler来决定的。这里,我直接给出公式:发生中断时间=(TIM_Period+1)(TIM_Prescaler+1)/FCLK,而FCLK为72M,所以定时1s,可以这样:TIM_Period=2000-1,TIM_Prescaler=36000-1;最后清除溢出中断标志,使能时钟即可计时。

(3)编写中断计时函数

void TIM2_IRQHandler(void)

{

    if(TIM_GetITStatus(TIM2 ,TIM_IT_Update)!=RESET)

    {

        sec++;

        if(sec>=60)

        {

            sec = 0;

            min++;

            if(min>=60)

            {

                min = 0;

                hour++;

                if(hour>=24)

                {

                    hour = 0;

                }

            }

        }

    }

    TIM_ClearITPendingBit(TIM2 ,TIM_FLAG_Update);

}

这里,先定义时、分、秒三个变量,然后在中断函数里,对时间变量的关系进行换算即可。

(4)编写时钟显示函数

        这里,我们采用LCD12864实时显示。LCD12864的相关内容,我后面在LCD库函数章节中,会专门介绍的。这里,只将时间显示即可。

    lcd_display_num_m(2, 16, hour/10);

    lcd_display_num_m(2, 24, hour%10);

    lcd_display_string(2,32,"时");

    lcd_display_num_m(2, 48, min/10);

    lcd_display_num_m(2, 56, min%10);

    lcd_display_string(2,64,"分");

    lcd_display_num_m(2, 80, sec/10);

    lcd_display_num_m(2, 88, sec%10);

    lcd_display_string(2,96,"秒");

        LCD12864的驱动函数,我跟着黄老师的视频后面写的,在老师的基础上,增加了汉字字符串显示函数。这里,看成库函数即可,只需简单的调用,显示时间就行。

(5)按键调整时间

        成功显示时间后,我们需要按键来调整时间。 我们需要设置时钟启/停键(K1),时间位选择键(K2),数值增加键(K3),数值减小键(K4)。

1我们先对按键的GPIO进行配置,开启相应的时钟,选择相关引脚,设置浮空输入模式等。

void key_gpio_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    /使能GPIO的RCC时钟/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    /配置PB11~PB14引脚/

    GPIO_InitStructureGPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;

    GPIO_InitStructureGPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructureGPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOB,&GPIO_InitStructure);

}

2配置好按键的GPIO口后,编写按键扫描函数,从而达到调整时间的功能。

u8 flag,mark;//flag为定时器启停标志位,mark为位选择标志位

//mark为0表示未选中,mark为1表示选择时位,mark为2表示选择分位,mark为3表示选择秒位

void keyscan(void)

{

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET)

    {

        delay_ms(10);

        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET)

        {

            flag = ~flag;

            if(!flag)

            {

                TIM_Cmd(TIM2, ENABLE);

            }

            else

            {

                TIM_Cmd(TIM2, DISABLE);

                mark = 0;

            }

        }while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET);

    }

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==RESET)

    {

        delay_ms(10);

        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==RESET)

        {

            mark = mark>=30:mark+1;

        }while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==RESET);

    }

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET)

    {

        delay_ms(10);

        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET)

        {

            if(flag)

            {

                switch(mark)

                {

                    case 1:hour = hour<23hour+1:0;break;

                    case 2:min = min<59min+1:0;break;

                    case 3:sec = sec<59sec+1:0;break;

                    default:break;

                }

            }

        }while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET);

    }

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET)

    {

        delay_ms(10);

        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET)

        {

            if(flag)

            {

                switch(mark)

                {

                    case 1:hour = hour>0hour-1:23;break;

                    case 2:min = min>0min-1:59;break;

                    case 3:sec = sec>0sec-1:59;break;

                    default:break;

                }

            }

        }while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET);

    }

}

        至此,我们完成了时钟显示的功能,当然,后期如果可以的话,我们可以使用stm32的RTC实时时钟资源,还可以设置闹钟、整点报时的功能。

         本章,我主要介绍了如何利用stm32的TIM定时器和GPIO资源,实现时钟显示和按键调整的功能。下一章中,我将介绍如何利用DHT11模块来测量温度和湿度,从而实现系统对环境参量的获取。

以上就是关于s7200系列可编程序控制器中读取内部时钟,用什么指令全部的内容,包括:s7200系列可编程序控制器中读取内部时钟,用什么指令、基于AT59S52和PCF8563的RTC实时时钟显示.、rtc实时时钟和单片机时钟的区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9481660.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存