技术标签: cpp
为了更好的封装,这个模块使用class封装。
class Cheetah
{
public:
Cheetah(struct UartLiteDev* uart, struct StampTimerDev* timer);
int set_value(u16 addr, u32 value, int timeout = 1000);
int get_value(u16 addr, u32* value, int timeout = 1000);
int set_value_retry(u16 addr, u32 value, int timeout = 1000, int count = 5) {
while(count--)
{
int ret = set_value(addr, value, timeout);
if (ret == 0)
return 0;
}
return -1;
}
int get_value_retry(u16 addr, u32* value, int timeout = 1000, int count = 5) {
while(count--)
{
int ret = get_value(addr, value, timeout);
if (ret == 0)
return 0;
}
return -1;
}
...
protected:
struct UartLiteDev* uart_;
struct StampTimerDev* timer_;
};
这个class里,定义了几个基础的方法,用来获取值或者设置值,这些值都是通过串口进行收发的,所以这里需要关联到一个串口结构体,这是整板的一个硬件资源,所以不使用内嵌,而使用指针关联。
另外,发送过程中,需要用到时间戳,所以,这个需要关联到一个TIMER,这也是整板的一个硬件资源,所以不使用内嵌,而使用指针关联。
其他的特定的函数,都是基于基础方法获取特定的值或者设置特定的值,为了便于使用,增加可读性,所以封装成独立的函数。
例如:
int get_current_hsize(u32* value) {
u32 data = 0;
int ret = get_value_retry(0x6090, &data);
if (ret < 0)
return -1;
*value = data;
return 0;
}
int get_exp_time_limit(u32* max_value, u32* min_value) {
u32 data = 0;
int ret = get_value_retry(0x6088, &data);
if (ret < 0)
return -1;
*max_value = data & 0xffffff;
*min_value = data >> 24;
return 0;
}
int get_cam_attri(u32* paio_en, u32* aec_en, u32* agc_en) {
u32 data = 0;
int ret = get_value_retry(0x60AC, &data);
if (ret < 0)
return -1;
plog("%x\r\n", data);
*paio_en = (data >> 29) & 0x1;
*aec_en = (data >> 30) & 0x1;
*agc_en = (data >> 31) & 0x1;
return 0;
}
int get_current_exp_time(u32* value) {
return get_value_retry(0x6080, value);
}
...
int set_software_reset() {
return set_value_retry(0x601c, 0xDEADBEEF);
}
int set_exposure_mode(u8 value) {
//0x0 – Off (Free Running)
//0x1 – Trigger Pulse Width (Duration of selected trigger pulse determines exposure time)
//0x2 – Internal (Exposure Time register sets exposure time in microseconds)
//0x3 – Reserved
return set_value_retry(0x0720, value);
}
int set_exposure_time(u32 value, int timeout = 1000) {
return set_value_retry(0x0728, value, timeout);
}
int set_digital_gain(u32 value, int timeout = 1000) {
return set_value_retry(0x0438, value, timeout);
}
...
来看看几个基础函数的实现,在CPP文件中,
首先是构建函数,
Cheetah::Cheetah(struct UartLiteDev* uart, struct StampTimerDev* timer) : uart_(uart), timer_(timer)
{
}
并没有做特殊的处理,只是在构建时进行了成员的初始化。
将传入的参数,即两个资源结构体的指针,赋值给成员变量uart_和timer_。
再来看get
int Cheetah::get_value(u16 addr, u32* value, int timeout)
{
struct RingBuffer* ring = &uart_->recv_buff;
u8 data = 0;
ring_buffer_clear(ring);
struct SensorReadCommand cmd = {0};
cmd.data[0] = 0x52;
cmd.data[1] = (addr >> 8) & 0xff;
cmd.data[2] = addr & 0xff;
uart_lite_send(uart_, (u8*)&cmd.data[0], sizeof(cmd.data));
struct SensorReadAck ack = {0};
u32 action_time = get_timestamp_ms(timer_);
while(ring_buffer_valid_len(ring) < sizeof(ack.data))
{
u32 now_time = get_timestamp_ms(timer_);
u32 dlt_time = ABS_DEC(now_time, action_time);
if (dlt_time > (u32)timeout) {
plog("Cheetah get_value:0x%x timeout!\r\n", addr);
return -1;
}
}
u8* rptr = (u8*)&ack.data[0];
for (int i = 0; i < sizeof(ack.data); i++)
{
ring_buffer_pop(ring, &rptr[i]);
}
if (ack.data[0] == 0x06) {
u32 val = (((u32)ack.data[1]) << 24) | (((u32)ack.data[2]) << 16) | (((u32)ack.data[3]) << 8) | (((u32)ack.data[4]) << 0);
*value = val;
return 0;
} else {
plog("Cheetah get_value:0x%x error!\r\n", addr);
return -1;
}
}
按照协议要求,
先发命令,
然后等待ACK,这里等待是定时等待的,如果不定时,则可能出现卡死,
然后取出ACK,并分析,并从ACK的数组中,取出所需要的数据。
这里,使用了几个结构体对data数组进行封装,是为了增加可读性。
struct SensorWriteCommand
{
u8 data[7];
};
struct SensorWriteAck
{
u8 data[2];
};
struct SensorReadCommand
{
u8 data[3];
};
struct SensorReadAck
{
u8 data[5];
};
再来看set
int Cheetah::set_value(u16 addr, u32 value, int timeout)
{
struct RingBuffer* ring = &uart_->recv_buff;
u8 data = 0;
//while(ring_buffer_pop(ring, &data) == 0);
ring_buffer_clear(ring);
struct SensorWriteCommand cmd = {0};
cmd.data[0] = 0x57;
cmd.data[1] = (addr >> 8) & 0xff;
cmd.data[2] = addr & 0xff;
cmd.data[3] = (value >> 24) & 0xff;
cmd.data[4] = (value >> 16) & 0xff;
cmd.data[5] = (value >> 8) & 0xff;
cmd.data[6] = value & 0xff;
uart_lite_send(uart_, (u8*)&cmd.data[0], sizeof(cmd.data));
if (timeout <= 0)
return 0;
struct SensorWriteAck ack = {0};
u32 action_time = get_timestamp_ms(timer_);
while(ring_buffer_valid_len(ring) < 1)
{
u32 now_time = get_timestamp_ms(timer_);
u32 dlt_time = ABS_DEC(now_time, action_time);
if (dlt_time > (u32)timeout) {
plog("Cheetah set_value:0x%x 0x%x timeout!!!\r\n", addr, value);
return -1;
}
}
ring_buffer_pop(ring, &ack.data[0]);
if (ack.data[0] == 0x15) {
action_time = get_timestamp_ms(timer_);
while(ring_buffer_valid_len(ring) < 1)
{
u32 now_time = get_timestamp_ms(timer_);
u32 dlt_time = ABS_DEC(now_time, action_time);
if (dlt_time > (u32)timeout) {
plog("Cheetah set_value:0x%x 0x%x timeout!!!\r\n", addr, value);
return -1;
}
}
ring_buffer_pop(ring, &ack.data[1]);
}
if (ack.data[0] == 0x06) {
return 0;
} else {
if (ack.data[0] == 0x15) {
if (ack.data[1] == 0x00) {
return 0;
}
else {
plog("Cheetah set_value:0x%x 0x%x error, ", addr, value);
if (ack.data[1] == 0x01) {
plog("Error Code: Invalid command\r\n");
} else if (ack.data[1] == 0x02) {
plog("Error Code: Time out\r\n");
} else if (ack.data[1] == 0x03) {
plog("Error Code: Checksum error\r\n");
} else if (ack.data[1] == 0x04) {
plog("Error Code: Value less then minimum\r\n");
} else if (ack.data[1] == 0x05) {
plog("Error Code: Value higher than maximum\r\n");
} else if (ack.data[1] == 0x06) {
plog("Error Code: AGC error\r\n");
} else if (ack.data[1] == 0x07) {
plog("Error Code: Supervisor mode error\r\n");
} else if (ack.data[1] == 0x07) {
plog("Error Code: Mode not supported error\r\n");
} else {
plog("Error Code: 0x%x: ack=0x%x 0x%x\r\n", addr, ack.data[0], ack.data[1]);
}
}
}
return -1;
}
}
按照协议要求,
先发命令,
然后等待ACK,这里等待是定时等待的,如果不定时,则可能出现卡死,
然后取出ACK,并分析,并从ACK的数组中,取出所需要的数据。
编辑:ll36MT160-ASEMI电机专用整流桥36A 1600V型号:36MT160品牌:ASEMII封装:D-63电性参数:36A 1600V正向电流:36A反向耐压:1600V引脚数量:5封装尺寸:如图特性:三相整流桥产品描述36MT160的电性参数:正向平均电流36A;反向峰值电压1600V36MT160的包装方式:100pcs/盒36MT160整流桥被广泛适用于:电源、充电器、适配器、LED灯饰、大小家电、民用及工业设备等产品中使用,整流桥_mt1602339349 vffubdp cn
声明:有人说, 有些面试题很变态,个人认为其实是因为我们基础不扎实或者没有深入。本篇文章来自一位很资深的前辈对于最近java面试题目所做的总结归纳,有170道题目 ,知识面很广 ,而且这位前辈对于每个题都自己测试给出了答案 ,如果你对某个题有疑问或者不明白,可以电脑端登录把题目复制下来然后发表评论,大家一起探讨,也可以电脑端登录后关注我给我发私信,我们一起进步!以下内容来自这位前辈..._java面试题
Knight MovesTime Limit: 1000MS Memory Limit: 30000KTotal Submissions: 19803 Accepted: 9150DescriptionBackgroundMr Somurolov, fabulous chess-gamer indeed, asserts
前言从本文标题就能看到靓丽的字眼:Spring框架bug。相信有的小伙伴心里小九九肯定会说:又是一篇标题党文章。此处可以很负责人的告诉大家:本人任何文章绝不哗众取宠,除了干货还是干货。相信关注过我的小伙伴都是知道的,我只递送干货,绝不标题党来浪费大家的时间和精力~那无异于谋财害命(说得严重了,不喜勿喷)本篇文章能让你知道exposeProxy=true真实作用实际和作用范围,从而能够更精..._exposeproxy true
本文共计:5852字;阅读需要:15分钟;目录导语1.QUIC是啥?1.1 什么是QUIC1.2 HTTP协议发展 1.2.1 HTTP历史进程 1.2.2 HTTP1.0和HTT..._协议开销大:header里携带的内容过大,且不能压缩,增加了传输的成本 传输不安全:采
这里写目录标题uniapp常见的错误未定义错误uniapp常见的错误未定义错误1、vue文件内部定义的方法未添加this app.vue里定义的通用函数,可以不加this
1.引入echarts库文件<script charset="utf-8" type="text/javascript" language="javascript" src="echarts-2.2.7/doc/example/www/js/echarts.js"></script> 2.在页面中新建div用于地图展示<div id="main" ...
1.格式化输出函数 printf()printf() 函数是c语言提供的标准输出函数,它的作用是向终端按指定格式输出若干个数据。(1)printf()函数的一般形式。printf(格式控制,输出表列);1.“格式控制”:用双引号括起来的字符串是“格式控制”字符串,它包括两种信息。格式转换说明,由“%”和格式字符组成需要原样输出的字符也写在格式控制内。“输出表列”:需要输出的一些数据,可以是常量、变量或表达式。输出表列中的各输出项用逗号隔开。(2)格式字符。可在“%”与格式字符之间插_关于数据输入输出格式讨论数据输入和输出需要一定的格式,请问:使用格式化输入函数scanf()、格式化输出函数printf()时,需要注意哪些问题?
为什么用双向 LSTM?单向的 RNN,是根据前面的信息推出后面的,但有时候只看前面的词是不够的, 例如,我今天不舒服,我打算__一天。只根据‘不舒服‘,可能推出我打算‘去医院‘,‘睡觉‘,‘请假‘等等,但如果加上后面的‘一天‘,能选择的范围就变小了,‘去医院‘这种就不能选了,而‘请假‘‘休息‘之类的被选择概率就会更大。 双向LST..._双向lstm模型的网络结构图
原创 2018-04-22 关注前沿科技 量子位安妮 栗子 发自 泽浩寺量子位 出品 | 公众号 QbitAI可能每个程序猿,都想过加入Google。然而想要“应试”成功,考验的不仅仅是开发人员的编程技术,还能侧面考验着参赛者的渠道来源是否广泛、背景力量是否强大、脑洞回路是否清奇……不过,梦是要做的,简历是要投的,说不准面试就来了呢?所以,我们需要为万一砸到头顶的面试,做好一万的准备。前有万千过桥...
什么是JMS MQ全称:Java MessageService 中文:Java 消息服务。JMS是Java的一套API标准,最初的目的是为了使应用程序能够访问现有的MO系统(MessageOriented Middleware),MOM指的是利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。后来被许多现有的MOM供应商采用,并实现为MOM系统。常见MOM系统包括Apache的ActiveMQ、 阿里巴巴的RocketMQ、IBM的MQSeries、Microsof
exercise练习