求C#窗体定时为100ms的心跳包的代码,是TCP的

求C#窗体定时为100ms的心跳包的代码,是TCP的,第1张

auto 局部变量(自动储存) break无条件退出程序最内层循环 case switch语句中选择项 char单字节整型数据 const定义不可更改的常量值 continue中断本次循环,并转向下一次循环 default switch语句中的默认选择项 do 用于构成dowhile循环语句 double定义双精度浮点型数据 else构成ifelse选择程序结构 enum枚举 extern在其它程序模块中说明了全局变量 float定义单精度浮点型数据 for构成for循环语句 goto构成goto转移结构 if构成ifelse选择结构 int基本整型数据 long长整型数据 registerCPU内部寄存的变量 return用于返回函数的返回值 short短整型数据 signed有符号数 sizoef计算表达式或数据类型的占用字节数 static定义静态变量 struct定义结构类型数据 switch构成switch选择结构 typedef重新定义数据类型 union联合类型数据 unsigned定义无符号数据 void定义无类型数据 volatile该变量在程序中执行中可被隐含地改变 while用于构成dowhile或while循环结构

这个是主程序和部分代码由于字数限制所以你还是留个邮箱吧

void main(void)

{

unsigned char i;

sys_init();

beep = 1;

LCD12864_DisplayOneLine(0x80,ucStr1); //显示信息1

LCD12864_DisplayOneLine(0x90,ucStr2); //显示信息2

LCD12864_DisplayOneLine(0x88,ucStr3); //显示信息3

LCD12864_DisplayOneLine(0x98,ucStr4); //显示信息4

while(1)

{

sendDataToProcessing('S', Signal); // 发送并处理原始脉搏传感器数据

if (QS == true){ // 确定发现一个心跳

fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse

sendDataToProcessing('B',BPM); // 发送一个'B'和心率

sendDataToProcessing('Q',IBI); // send time between beats with a 'Q' prefix

QS = false; // reset the Quantified Self flag for next time

LCD_disp_list_char(2,4,DisBuff);//在LCD12864上显示BPM

}

delay(138); // 延时 196ms

LCD_disp_list_char(4,4,DisBuff2);

//ledFadeToBeat();

if(Pressure<100){

for(i=0;i<8;i++){

delay(1000);}

if (Pressure<100){

beep = 0;}}

if(BPM<60|BPM>100){

for(i=0;i<9;i++){

delay(1000);}

if(BPM<60|BPM>100){

beep = 0;}

for(i = 0;i<16;i++) //依次执行写入 *** 作

{

putchar(ucStr1[i]);

}

for(i = 0;i<16;i++) //依次执行写入 *** 作

{

putchar(ucStr2[i]);

}

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

{

putchar(DisBuff[i]);}

for(i = 0;i<16;i++) //依次执行写入 *** 作

{

putchar(ucStr3[i]);

}

for(i = 0;i<16;i++) //依次执行写入 *** 作

{

putchar(ucStr4[i]);

}

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

{

putchar(DisBuff2[i]);}

}

}

//void ledFadeToBeat(){

// fadeRate -= 15; // set LED fade value

// fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers!

// analogWrite(fadePin,fadeRate); // fade LED

// }

/

函数名称:GetADCResult

函数功能:获取AD转换结果函数

入口参数:BYTE ch(通道选择)

返回值:result(A/D转换结果)

备注:无

/

unsigned int GetADCResult(BYTE ch)

{ unsigned int result; //AD转换结果result

ADC_CONTR&=0xf8; //清除ADC控制寄存器ADC CONTR的CHS2、CHS1、CHS0(清除通道选择)

_nop_(); //设置ADC CONTR控制寄存器后,要加4个空 *** 作延时才可以正确读到ADC CONTR寄存器的值

_nop_();

_nop_();

_nop_();

ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; //开ADC电源,选择AD转换速率,并选择AD通道,开始AD转换

_nop_(); //设置ADC CONTR控制寄存器后,要加4个空 *** 作延时才可以正确读到ADC CONTR寄存器的值

_nop_();

_nop_();

_nop_();

while (!(ADC_CONTR & ADC_FLAG));//等待AD转换结束

ADC_CONTR &= ~ADC_FLAG; //关闭ADC

result=ADC_RES; //将AD转换结果的高两位赋给result

result=result<<8; //将result循环左移8位

result+=ADC_RESL; //将AD转换结果的底8位加高两位共10位给result

return result; //返回10位AD转换结果

}

void sendDataToProcessing(char symbol, int dat ){

putchar(symbol); // symbol prefix tells Processing what type of data is coming

printf("%d\r\n",dat); // the data to send culminating in a carriage return

}

void UART_init(void)

{

TMOD = 0x20; //定时器工作在定时器1的方式2

PCON = 0x00; //不倍频

SCON = 0x50; //串口工作在方式1,并且启动串行接收

TH1 = 0xFd; //设置波特率 9600

TL1 = 0xFd;

TR1 = 1; //启动定时器1

}

char putchar(unsigned char dat)

{

TI=0;

SBUF=dat;

while(!TI);

TI=0;

return SBUF;

}

void _nop_ (void)

{}

void T0_init(void){

// Initializes Timer0 to throw an interrupt every 2mS

TMOD |= 0x01; //16bit TIMER

TL0=T0MS;

TH0=T0MS>>8;

TR0=1; //start Timer 0

ET0=1; //enable Timer Interrupt

EA=1; // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED

}

void T1_init(void){

// Initializes Timer0 to throw an interrupt every 2mS

TMOD |= 0x01; //16bit TIMER

TL1=T0MS2;

TH1=T0MS2>>8;

TR1=1; //start Timer 0

ET1=1; //enable Timer Interrupt

EA=1; // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED

}

void ADC_init(unsigned char channel)

{

P1ASF=ADC_MASK<<channel; //选择P1 channel作为A/D输入来用

ADC_RES=0; //清除ADC结果寄存器RES

ADC_RESL=0; //清除ADC结果寄存器RESL

AUXR1 |= 0x04; //调整ADC格式的结果

}

void Timer1_rountine(void) interrupt 1

{}

unsigned int analogRead(unsigned char channel)

{

unsigned int result;

while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag

ADC_CONTR &=!ADC_FLAG; //clear ADC FLAG

result=ADC_RES;

result=result<<8;

result+=ADC_RESL;

// ADC_CONTR|=channel|ADC_POWER|ADC_SPEEDLL|ADC_START;

return result;

}

// Timer 0中断子程序,每2MS中断一次,读取AD值,计算心率值

void Timer0_rountine(void) interrupt 1

{

int N;

unsigned char i;

// keep a running total of the last 10 IBI values

unsigned int runningTotal = 0; // clear the runningTotal variable

EA=0; // 关定时器中断

TL0=T0MS;

TH0=T0MS>>8; //重装16位定时器初值

Pressure = (GetADCResult(PressurePin)); //

DisBuff2[3] = Pressure%10+48;//取个位数

DisBuff2[2] = Pressure%100/10+48; //取十位数

DisBuff2[1] = Pressure%1000/100+48; //百位数

DisBuff2[0] = Pressure/1000+48;//取千位数

Signal = GetADCResult(PulsePin); // 读脉搏传感器

sampleCounter += 2; // 使用这个值跟踪记录脉搏时间间隔在ms级

N = sampleCounter - lastBeatTime; // 减上个节拍的时间来避免噪声

// 找到脉搏波的波峰和波谷

if(Signal < thresh && N > (IBI/5)3){ // 如果脉搏传感器输出小于电源电压一半 并且 消除噪声时间小于 3/5个脉搏时间间隔

if (Signal < Trough){ // 如果脉搏传感器输出小于波谷

Trough = Signal; // 跟踪脉搏波的最低点

}

}

if(Signal > thresh && Signal > Peak){ // 如果输出大于电源电压一半并且大于波峰

Peak = Signal; // 将新值设为波峰

} // 跟踪脉搏波的波峰

if (N > 250){ // 避免高频噪声

if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)3) ){

Pulse = true; // 当检测到一个脉搏时将脉搏标志设为真

blinkPin=0; // 点亮脉搏灯

IBI = sampleCounter - lastBeatTime; // 测量两个脉搏的时间in mS

lastBeatTime = sampleCounter; // 跟踪脉搏时间

if(secondBeat){ // 如果这是第二个脉搏

secondBeat = false; // 清除标识

for(i=0; i<=9; i++){ // 全部的数据作为真实脉搏BMP

rate[i] = IBI;

}

}

if(firstBeat){ // 如果是第一个脉搏

firstBeat = false; // 清除标志

secondBeat = true; // 设置第二脉搏标志

EA=1; //开中断

return; // IBI 值是不可靠的所以抛弃

}

for(i=0; i<=8; i++){ // 移动数据在rate数组中

rate[i] = rate[i+1]; // 顶替旧值

runningTotal += rate[i]; // 加上第九个新值

}

rate[9] = IBI; // 加最后的IBI到rate数组中

runningTotal += rate[9]; // 加上一个IBI到runningTotal

runningTotal /= 10; // 取平均值

BPM = 60000/runningTotal; // 一分钟可以检测到多少个心跳及 BPM!

if(BPM>200)BPM=200; //限制BPM最高显示值

if(BPM<30)BPM=30; //限制BPM最低显示值

DisBuff[2] = BPM%10+48;//取个位数

DisBuff[1] = BPM%100/10+48; //取十位数

DisBuff[0] = BPM/100+48; //百位数

if(DisBuff[0]==48)

DisBuff[0]=32;

QS = true; // 设置QS标志

// QS FLAG IS NOT CLEARED INSIDE THIS ISR

}

}

if (Signal < thresh && Pulse == true){ // 当电压归零节拍结束

blinkPin=1; // 熄灭脉搏灯

Pulse = false; // 重置脉搏标识我们可以重新测

amp = Peak - Trough; // 得到脉搏波的峰峰值

thresh = amp/2 + Trough; // 设置thresh位脉搏峰峰值的一半

Peak = thresh; // 为下一次测试重置波峰

Trough = thresh;

}

if (N > 2500){ //如果超过25秒没有检测到一个脉搏

thresh = 512; // 重新设置波谷

Peak = 512; // 重新设置波峰

Trough = 512; // 重新设置间隔

lastBeatTime = sampleCounter; // 把最后的节拍时间更新

firstBeat = true; // 重新设置标志避免噪声

secondBeat = false; // 当我们得到心跳的时候

}

EA=1; // 开中断

}// end isr

由于延时函数和系统时钟频率密切相关,所以stm32的固件库里没有delay_ms()函数可供直接调用。

帮你贴一段代码:

//////////////////////////////////////////////////////////////////////////////////

//延时程序

//邓尧

//2014515

//10

//Copyright(C)

//All rights reserved

//////////////////////////////////////////////////////////////////////////////////

#include

//////////////////////////////////////////////////////////////////////////////////

static u8 fac_us=0; //us延时倍乘数

static u16 fac_ms=0; //ms延时倍乘数

////////////////////////////////////////

//初始化延迟函数

//SYSTICK的时钟固定为HCLK时钟的1/8

//SYSCLK:系统时钟 如72

////////////////////////////////////////

void delay_init(u8 SYSCLK)

{

SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟 HCLK/8

fac_us=SYSCLK/8;

fac_ms=(u16)fac_us1000;

}

////////////////////////////////////////

//延时nms

//注意nms的范围

//SysTick->LOAD为24位寄存器,所以,最大延时为:

//nms<=0xffffff81000/SYSCLK

//SYSCLK单位为Hz,nms单位为ms

//对72M条件下,nms<=1864

////////////////////////////////////////

void delay_ms(u16 nms)

{

u32 temp;

SysTick->LOAD=(u32)nmsfac_ms;//时间加载(SysTick->LOAD为24bit)

SysTick->VAL =0x00; //清空计数器

SysTick->CTRL=0x01 ; //开始倒数

do

{

temp=SysTick->CTRL;

}

while(temp&0x01&&!(temp&(1<<16)));//等待时间到达

SysTick->CTRL=0x00; //关闭计数器

SysTick->VAL =0X00; //清空计数器

}

////////////////////////////////////////////

//延时nus

//nus为要延时的us数

/////////////////////////////////////////////

void delay_us(u32 nus)

{

u32 temp;

SysTick->LOAD=nusfac_us; //时间加载

SysTick->VAL=0x00; //清空计数器

SysTick->CTRL=0x01 ; //开始倒数

do

{

temp=SysTick->CTRL;

}

while(temp&0x01&&!(temp&(1<<16)));//等待时间到达

SysTick->CTRL=0x00; //关闭计数器

SysTick->VAL =0X00; //清空计数器

}

////////////////////END//////////////////////////////////////////

这里的滴答时钟能精确的达到定时的效果,但是这里有一个注意的地方就是当你用滴答时钟做延时函数时,一旦你运行延时函数,CPU将处于空闲状态,一般这种状态下只有外部或者内部中断才能打断,但是需要注意的是滴答时钟的中断优先级高于我们能够配置的外部中断优先级,所以你在延时时如果想使用外部中断进行打断的话效果将不太理想,这也是我自己遇到的一个问题,至今没有一个很好的解决办法,所以如果我要在延时中进行打断的话,我一般不用滴答时钟作为我的延时定时器。而是用高级定时器或者通用定时定时,并且能在想中断时,用优先级高的中断进行打断,这里又设计到了一个问题就是外部中断的使用和STM32优先级的使用和优先级的学习,呵呵,说着说着就发现这些东西不是一两句话就能说清的,慢慢来吧,我有时间的时候就会把这些学习的心得公布在网上,希望能有更多的人能读到,有所成长。

滴答时钟它本来是用给 *** 作系统提供一个“心跳”频率,能够实现优先级的判定和任务之间的切换,是维持 *** 作系统的根本。一般在UCOSII系统中滴答时钟每10MS中断一次,在中断里调用任务调度函数,实现多任务系统的正常运作,当然前提必须把UCOSII移植到STM32中,当然这个会在后续的记录中说UCOSII的使用,这个也是一个大的模块,希望能有这么多的精力去把它分享出来给大家,我只是在这里提起一下滴答时钟,它是一个很好用的定时器,用好了是神器,我也希望能更加深入和全面的说讲解下它,现在只是说起它,希望有心之人也能去研究研究下它。

摆线(cycloid)

点击下图查看动画

https://gss0baiducom/70cFfyinKgQFm2e88IuM_a/baike/pic/item/2cb4fefe59cd78265d600825jpg

摆线的定义

摆线是数学中众多的迷人曲线之一.它是这样定义的:一个圆沿一直线缓慢地滚动,则圆上一固定点所经过的轨迹称为摆线

摆线别称及原因

一个圆在一条定直线上滚动时,圆周上一个定点的轨迹。又称旋轮线。圆上定点的初始位置为坐标原点,定直线为x轴。当圆滚动j 角以后,圆上定点从 O 点位置到达P点位置。当圆滚动一周,即 j从O变动2π时,动圆上定点描画出摆线的第一拱。 再向前滚动一周, 动圆上定点描画出第二拱,继续滚动,可得第三拱,第四拱……,所有这些拱的形状都是完全相同的 ,每一拱的拱高为2a(即圆的直径),拱宽为2πa(即圆的周长)。摆线有一个重要性质,即当一物体仅凭重力从A点滑落到不在它正下方的B点时,若沿着A,B间的摆线,滑落所需时间最短,因此摆线又称最速降曲线。

摆线的性质

到17 世纪,人们发现摆线具有如下性质:

1.它的长度等于旋转圆直径的 4 倍.尤为令人感兴趣的是,它的长度是 一个不依赖于π的有理数.

2.在弧线下的面积,是旋转圆面积的三倍.

3.圆上描出摆线的那个点,具有不同的速度——事实上,在特定的地方它甚至是静止的.

4.当d子从一个摆线形状的容器的不同点放开时,它们会同时到达底部

摆线的出现及争议

摆线最早出现可见于公元 1501 年出版的 C·鲍威尔的一本书中.但在 17 世 纪,大批卓越的数学家(如伽利略,帕斯卡,托里拆利,笛卡儿,费尔马, 伍任,瓦里斯,惠更斯,约翰·伯努里,莱布尼兹,牛顿等等)热心于研究这一曲线的性质.17 世纪是人们对数学力学和数学运动学爱好的年代,这能 解释人们为什么对摆线怀有强烈的兴趣.在这一时期,伴随着许多发现,也出现了众多有关发现权的争议,剽窃的指责,以及抹煞他人工作的现象.这 样,作为一种结果,摆线被贴上了引发争议的“金苹果”和“几何的海伦” 的标签.

摆线的相关故事

时钟与摆线

时钟已变成现代人不可或少的必备工具之一,没有时钟,人们将不知时间,许多重要的约会便会错过,当各位在看表的时候,不知可曾想过,时钟里面隐藏了些甚么道理,一砂一世界,许多我们视为理所当然的事都是先民流血流汗一点一滴累积而成的

在时钟里面到底隐藏了甚么东西 将这些理论写出来可是厚厚的一大本呢!回想以前的中世纪航海时代,时间的掌握是关乎全船人生命安危的大事,想要和大海搏斗,时间是不可或缺的因数,古时候是以沙漏水钟来计时,但这些计时工具相当不准确,为了增加船员生存的机会,发明精确的计时器变成了当时科学界的当务之急

那时在意大利有一位年青科学家伽利略,有一次在比萨斜塔处意外地发现一个有趣的现象,教堂的吊灯来回摆动时,不管摆动的幅度大还是小,每摆动一次用的时间都相等当时,他是以自己的心跳脉搏来计算时间的从此以后,伽利略便废寝忘食的研究起物理和数学来他曾用自行制的滴漏来重新做单摆的试验,结果证明了单摆摆动的时间跟摆幅没有关系,只跟单摆摆线的长度有关这个现象使伽利略想到或许可以利用单摆来制作精确的时钟,但他始终并没有将理想付之实行

伽利略的发现振奋了科学界,可是不久便发现单摆的摆动周期也不完全相等原来,伽利略的观察和实验还不够精确实际上,摆的摆幅愈大,摆动周期就愈长,只不过这种周期的变化是很小的所以,如果用这种摆来制作时钟,摆的振幅会因为摩擦和空气阻力而愈来愈小,时钟也因此愈走愈快

过了不久,荷兰科学家决定要做出一个精确的时钟来伽利略的单摆是在一段圆弧上摆动的,所以我们也叫做圆周摆荷兰科学家想要找出一条曲线,使摆沿著这样的曲线摆动时,摆动周期完全与摆幅无关这群科学家放弃了物理实验,纯粹往数学曲线上去研究,经过不少次的失败,这样的曲线终於找到了,数学上把这种曲线叫做“摆线”,“等时曲线”或“旋轮线”

如果你用硬纸板剪一个圆,在圆的边缘固定一枝铅笔,当这圆沿一条直线滚动时,铅笔便会画出一条摆线来相信这样的玩具许多人都已经看过玩过,以前的街上,常会看到街边小贩再兜售这种摆线玩具,许多人赞叹摆线的美丽,但却不知摆线与时钟的相关性钟表店里面那些有钟摆的时钟,都是利用摆线性质制作出来的由于摆线的发现,使的精确时钟的制作不是梦想这也使人类科技向前迈进一大步

行星摆线传动机构的基本原理

摆线针轮行星传动中,摆线轮齿廓曲线运用内啮合发生圆产生的短幅外摆线。这种摆线曲线的生成原理如词条图所示。

有一发生圆(滚圆)半径为rp',基圆半径为rc',基园内切于发生圆,当发生圆绕基圆作纯滚动,其圆心Op分别处于Op1、Op2、Op3、Op4、Op5、Op6各位置时,由此固结在发生圆平面上的点M分别经过M1、M2、M3、M4、M5、M6各位置,由此发生圆周期滚动,发生圆上点M所形成的轨迹曲线即为短幅外摆线。

由以上摆线生成的几何关系 若仍保持以上的内切滚动关系,将基圆和摆线视为刚体相对于发生圆运动,则形成了摆线图形相对发生圆圆心Op作行星方式的运动,这就是行星摆线传动机构的基本原理。

PS :摆线方程

x=a(t-sint)

y=a(1-cost)

摆线最为最速曲线,只有在你学习了高等数学之后才能更好的理解它,接受它

∵f(t)=24sin160πt+110,

∴T=

160π

=

1

80

∴此人每分钟心跳次数为

1

T

=80

故答案为:80.

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

原文地址: http://outofmemory.cn/langs/11669470.html

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

发表评论

登录后才能评论

评论列表(0条)

保存