OC中char/short/int/float/double在64位系统中所占字节数

        size_t charSize = sizeof(char);
        NSLog(@"charSize = %zu", charSize);
        
        size_t shortSize = sizeof(short);
        NSLog(@"shortSize = %zu", shortSize);
        
        size_t intSize = sizeof(int);
        NSLog(@"intSize = %zu", intSize);
        
        size_t floatSize = sizeof(float);
        NSLog(@"floatSize = %zu", floatSize);
        
        size_t doubleSize = sizeof(double);
        NSLog(@"doubleSize = %zu", doubleSize);


打印结果如下:

2017-03-31 21:37:47.747874 Sizeof[19698:1349743] charSize = 1
2017-03-31 21:37:47.748010 Sizeof[19698:1349743] shortSize = 2
2017-03-31 21:37:47.748022 Sizeof[19698:1349743] intSize = 4
2017-03-31 21:37:47.748031 Sizeof[19698:1349743] floatSize = 4
2017-03-31 21:37:47.748040 Sizeof[19698:1349743] doubleSize = 8



#include "esImageData.h" #include "dcmtk/dcmdata/dcfilefo.h" #include "dcmtk/dcmimgle/dcmimage.h" #include "dcmtk/dcmjpeg/djdecode.h" /* for dcmjpeg decoders */ #include "dcmtk/dcmjpeg/djencode.h" /* for dcmjpeg encoders */ #include "dcmtk/dcmdata/dcrledrg.h" /* for DcmRLEDecoderRegistration */ #include "dcmtk/dcmdata/dcrleerg.h" /* for DcmRLEEncoderRegistration */ #include "dcmtk/dcmjpeg/dipijpeg.h" /* for dcmimage JPEG plugin */ #include "dcmtk/config/osconfig.h" #include "dcmtk/ofstd/ofstdinc.h" #include "dcmtk/dcmdata/dctk.h" #include "dcmtk/dcmdata/cmdlnarg.h" #include "dcmtk/dcmimage/diregist.h" #include "dcmtk/ofstd/ofstd.h" #include "dcmtk/dcmimgle/digsdfn.h" #include <QDebug> #pragma execution_character_set("utf-8") esImageData::esImageData(QObject *parent) : QObject(parent) { setAutoDelete(false); m_readFlag = false; m_dcmFile = new DcmFileFormat; opt_oxfer = EXS_LittleEndianExplicit; m_RescaleIntercept = 0; m_RescaleSlope = 1; } esImageData::~esImageData() { if (m_dcmFile != NULL) { m_dcmFile->clear(); delete m_dcmFile; m_dcmFile = NULL; } } bool esImageData::GetReadFlag() { return m_readFlag; } DcmFileFormat *esImageData::GetDcmFileFormat() { return m_dcmFile; } void esImageData::spacing(double spacing[3]) { spacing[0] = m_spaceX; spacing[1] = m_spaceY; spacing[2] = m_spaceZ; } void esImageData::ImagePositionPatient(double ImagePositionPatient[3]) { for (size_t i = 0; i < 3; i++) { ImagePositionPatient[i] = m_ImagePositionPatient[i]; } } bool esImageData::DicomImageToPixmap(DicomImage& dcmImage, QPixmap& pixmap) { bool res = true; void* pDIB = nullptr; int size = 0; if (dcmImage.isMonochrome()) { // 灰度图像 size = dcmImage.createWindowsDIB(pDIB, 0, 0, 8, 1, 1); if (!pDIB) return false; res = UcharArrayToPixmap((uchar*)pDIB, dcmImage.getWidth(), dcmImage.getHeight(), size, pixmap); } else { // RGB图像 size = dcmImage.createWindowsDIB(pDIB, 0, 0, 24, 1, 1); if (!pDIB) return false; res = UcharArrayToPixmap((uchar*)pDIB, dcmImage.getWidth(), dcmImage.getHeight(), size, pixmap, 24); } delete pDIB; return res; } bool esImageData::UcharArrayToPixmap(uchar* data, int w, int h, int bitSize, QPixmap& pixmap, int biBitCount) { //图文件由四部分依序组成:BITMAPFILEHEADER,BITMAPINFOHEADER,调色板,Image Data。 BITMAPFILEHEADER lpfh;// 文件头 固定的14个字节, 描述文件的有关信息 BITMAPINFOHEADER lpih;// 固定的40个字节,描述图像的有关信息 RGBQUAD palette[256];// 调色板RGBQUAD的大小就是256 memset(palette, 0, sizeof(palette)); for (int i = 0; i < 256; ++i) { palette[i].rgbBlue = i; palette[i].rgbGreen = i; palette[i].rgbRed = i; } memset(&lpfh, 0, sizeof(BITMAPFILEHEADER)); lpfh.bfType = 0x4d42;//'B''M' must be 0x4D42. //the sum bits of BITMAPFILEHEADER,BITMAPINFOHEADER and RGBQUAD;the index byte of the image data. lpfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(palette); memset(&lpih, 0, sizeof(BITMAPINFOHEADER)); lpih.biSize = sizeof(BITMAPINFOHEADER); //the size of this struct. it is 40 bytes. lpih.biWidth = w; lpih.biHeight = h; lpih.biCompression = BI_RGB; lpih.biPlanes = 1; //must be 1. void* pDIB = data; int size = bitSize; lpih.biBitCount = biBitCount; //the size of the whole bitmap file. lpfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(palette) + size; QByteArray bmp; bmp.append((char*)&lpfh, sizeof(BITMAPFILEHEADER)); bmp.append((char*)&lpih, sizeof(BITMAPINFOHEADER)); bmp.append((char*)palette, sizeof(palette)); bmp.append((char*)pDIB, size); return pixmap.loadFromData(bmp); } bool esImageData::ReadDicomFile(const QString& filename) { m_readFlag = false; m_filename = filename; QByteArray fileNameba = filename.toLocal8Bit(); OFCondition oc = m_dcmFile->loadFile(OFFilename(fileNameba.data())); if (oc.bad()) { qDebug() <<"read "<< fileNameba.data() << " Fail:" << oc.text(); return false; } DcmDataset* dataset = 0; OFCondition result; const char* value = nullptr; if (!(dataset = m_dcmFile->getDataset())) return false; result = dataset->findAndGetFloat64(DCM_PixelSpacing, m_spaceX, 1); if (result.bad()) m_spaceX = 1; result = dataset->findAndGetFloat64(DCM_PixelSpacing, m_spaceY, 0); if (result.bad()) m_spaceY = 1; result = dataset->findAndGetFloat64(DCM_SpacingBetweenSlices, m_spaceZ); if (result.bad()) { result = dataset->findAndGetFloat64(DCM_SliceThickness, m_spaceZ); if (result.bad()) m_spaceZ = 1; } result = dataset->findAndGetFloat64(DCM_WindowWidth, m_winWidth); result = dataset->findAndGetFloat64(DCM_WindowCenter, m_winCenter); //信息获取 //Patient related information OFString pid, pname, psex, pbirth; dataset->findAndGetOFString(DCM_PatientID, pid); //m_PatientId = QString(pid.c_str()); m_PatientId = QString(pid.c_str()); dataset->findAndGetOFString(DCM_PatientName, pname); //m_PatientName = QString(pname.c_str()); m_PatientName = QString(pname.c_str()); dataset->findAndGetOFString(DCM_PatientBirthDate, pbirth); m_PatientBirth = QString(pbirth.c_str()); dataset->findAndGetOFString(DCM_PatientSex, psex); //m_PatientGender = QString(psex.c_str()); m_PatientGender = QString(psex.c_str()); //study related information OFString snumber, sid, sdate, stime, sdescription, sbodypart; dataset->findAndGetOFString(DCM_AccessionNumber, snumber); m_AccessionNumber = QString(snumber.c_str()); dataset->findAndGetOFString(DCM_StudyInstanceUID, sid);//unique m_StudyInstanceId = QString(sid.c_str()); dataset->findAndGetOFString(DCM_StudyDate, sdate); dataset->findAndGetOFString(DCM_StudyTime, stime); m_StudyDate = QString(sdate.c_str()); m_StudyDateTime = QString(sdate.c_str()) + " " + QString(stime.c_str()).left(6); dataset->findAndGetOFString(DCM_StudyDescription, sdescription); //m_StudyDescription = QString(sdescription.c_str()); m_StudyDescription = QString(sdescription.c_str()); dataset->findAndGetOFString(DCM_BodyPartExamined, sbodypart); //m_StudyBodyPart = QString(sbodypart.c_str()); m_StudyBodyPart = QString(sbodypart.c_str()); //Series related information OFString id, number, time, date, description, modality, imageorient; dataset->findAndGetOFString(DCM_SeriesInstanceUID, id); m_SeriesInstanceId = QString(id.c_str()); dataset->findAndGetOFString(DCM_SeriesNumber, number); m_SeriesNumber = QString(number.c_str()); dataset->findAndGetOFString(DCM_InstanceNumber, number); m_InstanceNumber = QString(number.c_str()); result = dataset->findAndGetFloat64(DCM_ImagePositionPatient, m_ImagePositionPatient[0], 0); if (result.bad()) { } result = dataset->findAndGetFloat64(DCM_ImagePositionPatient, m_ImagePositionPatient[1], 1); if (result.bad()) { } result = dataset->findAndGetFloat64(DCM_ImagePositionPatient, m_ImagePositionPatient[2], 2); dataset->findAndGetOFString(DCM_Modality, modality); m_SeriesModality = QString(modality.c_str()); dataset->findAndGetOFString(DCM_SeriesDescription, description); //m_SeriesDescription = QString(description.c_str()); m_SeriesDescription = QString(description.c_str()); dataset->findAndGetOFString(DCM_ImageOrientationPatient, imageorient); m_SeriesImageOrientation = QString(imageorient.c_str()); //图像信息 OFString RescaleIntercept, RescaleSlope; result=dataset->findAndGetOFString(DCM_RescaleIntercept, RescaleIntercept); if (result.good()) { m_RescaleIntercept = QString(RescaleIntercept.c_str()).toDouble(); } result=dataset->findAndGetOFString(DCM_RescaleSlope, RescaleSlope); if (result.good()) { m_RescaleSlope = QString(RescaleSlope.c_str()).toDouble(); } dataset->findAndGetUint16(DCM_PixelRepresentation, m_PixelRepresentation); dataset->findAndGetUint16(DCM_SamplesPerPixel, m_SamplesPerPixel); dataset->findAndGetUint16(DCM_BitsAllocated, m_BitsAllocated); Uint16 nRows = 0; dataset->findAndGetUint16(DCM_Rows, nRows); this->m_Height = (int)nRows; Uint16 nCols = 0; dataset->findAndGetUint16(DCM_Columns, nCols); this->m_Width = (int)nCols; //this->m_Depth = fileCount; //this->m_SizeofImage = m_Height * m_Width; this->m_AlignWidth = (m_Width + 3) / 4 * 4; //4字节对齐 unsigned short bytes_per_pixel = m_BitsAllocated * m_SamplesPerPixel / 8; m_ImageArraySize = m_Width * m_Height * bytes_per_pixel; OFString window_width, window_center; dataset->findAndGetOFString(DCM_WindowWidth, window_width); dataset->findAndGetOFString(DCM_WindowCenter, window_center); const char* c = window_center.data(); this->m_WindowCenter = atoi(c); const char* w = window_width.data(); this->m_WindowWidth = atoi(w); //-------------------------------------------------------- m_readFlag = true; return true; } bool esImageData::LoadPixelData(Uint8*&pixelData, int &pixelType) { return LoadPixelData(m_dcmFile->getDataset(), pixelData, pixelType); } QString esImageData::GetTagInfo(Uint16 g, Uint16 e) { QString str; DcmDataset* dataset = m_dcmFile->getDataset(); if (dataset) { OFString ofstr; dataset->findAndGetOFString(DcmTagKey(g,e), ofstr); str = QString(ofstr.c_str()); } dataset = NULL; return str; } bool esImageData::DecompressFile(DcmDataset* dataset) { bool resFlag=true; /********解压缩**********/ const char* transferSyntax = nullptr; m_dcmFile->getMetaInfo()->findAndGetString(DCM_TransferSyntaxUID, transferSyntax); OFCondition error = EC_Normal; if (strcmp(transferSyntax,UID_JPEGProcess14SV1TransferSyntax)==0 || strcmp(transferSyntax , UID_JPEGProcess2_4TransferSyntax) == 0 || strcmp(transferSyntax , UID_JPEGProcess14TransferSyntax) == 0 || strcmp(transferSyntax , UID_JPEGProcess1TransferSyntax) == 0) { error=dataset->chooseRepresentation(opt_oxfer, nullptr); } else if (strcmp(transferSyntax ,UID_RLELosslessTransferSyntax)==0) { error=dataset->chooseRepresentation(opt_oxfer, nullptr); } if (error.bad()) { if (error == EJ_UnsupportedColorConversion) qDebug() << ("Try --conv-never to disable color space conversion\n"); else if (error == EC_CannotChangeRepresentation) qDebug()<<QString("Input transfer syntax %1 not supported").arg(transferSyntax); resFlag = false; } return resFlag; } bool esImageData::LoadPixelData(DcmDataset* dataset, Uint8*&pixelData,int& pixelType) { bool resFlag = false; bool decompressFlag = true; DcmXfer xfer (dataset->getOriginalXfer()); const char* xfer_id = xfer.getXferID(); if ((strcmp(xfer_id, UID_BigEndianExplicitTransferSyntax)) && (strcmp(xfer_id, UID_LittleEndianImplicitTransferSyntax)) && (strcmp(xfer_id, UID_LittleEndianExplicitTransferSyntax))) { decompressFlag = DecompressFile(dataset); } if (!decompressFlag) return resFlag; DcmElement* element = NULL; if (dataset->findAndGetElement(DCM_PixelData, element).good()) { //element->detachValueField(); Uint8*tmpPixelData = NULL; OFCondition result = element->getUint8Array(tmpPixelData); if (result.good() && tmpPixelData) { memcpy(pixelData, tmpPixelData, m_ImageArraySize); pixelType = 0; resFlag = true; } } else if (dataset->findAndGetElement(DCM_FloatPixelData, element).good()) { Float32*tmpPixelData = NULL; //element->detachValueField(); OFCondition result = element->getFloat32Array(tmpPixelData); if (result.good() && tmpPixelData) { memcpy(pixelData, (Uint8*)tmpPixelData, m_ImageArraySize); pixelType = 0; resFlag = true; } } else if (dataset->findAndGetElement(DCM_DoubleFloatPixelData, element).good()) { //element->detachValueField(); Float64*tmpPixelData = NULL; OFCondition result = element->getFloat64Array(tmpPixelData); if (result.good() && tmpPixelData) { memcpy(pixelData, (Uint8*)tmpPixelData, m_ImageArraySize); pixelType = 0; resFlag = true; } dataset->remove(DCM_PixelData); } //if (element) //{ // delete element; // element = NULL; //} //DicomImage * m_pDcmImage = new DicomImage(m_dcmFile, dataset->getOriginalXfer(), CIF_TakeOverExternalDataset); //if (m_pDcmImage->getStatus() == EIS_Normal) //{ // const DiPixel *pixel = m_pDcmImage->getInterData(); // memcpy(pixelData, pixel->getData(), m_ImageArraySize); // resFlag = true; //} //delete m_pDcmImage; return resFlag; } bool esImageData::RescaledImageDataIsDecimal() { return RescaledImageDataIsDecimal(m_RescaleSlope, m_RescaleIntercept); } bool esImageData::RescaledImageDataIsSigned() { return RescaledImageDataIsSigned(m_PixelRepresentation,m_RescaleSlope, m_RescaleIntercept); } bool esImageData::RescaledImageDataIsDecimal(double RescaleSlope,double RescaleOffset) { int s = int(RescaleSlope); int o = int(RescaleOffset); float sf = float(s); float of = float(o); double d1 = fabs(sf - RescaleSlope); double d2 = fabs(of - RescaleOffset); if (d1 > 0.0 || d2 > 0.0) { return true; } else { return false; } } bool esImageData::RescaledImageDataIsSigned(int PixelRepresentation,double RescaleSlope, double RescaleOffset) { bool rescaleSigned = (RescaleSlope < 0.0); bool pixelRepSigned = (PixelRepresentation == 1); bool offsetSigned = (RescaleOffset < 0.0); return (rescaleSigned || pixelRepSigned || offsetSigned); } //------------------------------------- //线程池加速 #include "vtkSetGet.h" int esImageData::GetScalarType() { DcmDataset*dataset = m_dcmFile->getDataset(); int destScalarType = -1; DcmElement* element = NULL; if (dataset->findAndGetElement(DCM_FloatPixelData, element).good()) { destScalarType = VTK_FLOAT; } else if (dataset->findAndGetElement(DCM_DoubleFloatPixelData, element).good()) { destScalarType = VTK_DOUBLE; } else if (dataset->findAndGetElement(DCM_PixelData, element).good()) { double rescaleIntercept = this->RescaleIntercept(); double rescaleSlope = this->RescaleSlope(); bool isFloat = this->RescaledImageDataIsDecimal(); bool signedFlag = this->RescaledImageDataIsSigned(); int bitAllocated = this->BitsAllocated(); if (bitAllocated == 8) { destScalarType = VTK_UNSIGNED_CHAR; } else if (bitAllocated == 16) { if (signedFlag) destScalarType = VTK_SHORT; else destScalarType = VTK_UNSIGNED_SHORT; } else if (bitAllocated == 32) { destScalarType = VTK_INT; if (isFloat) destScalarType = VTK_FLOAT; } else destScalarType = -1; } //if (element) //{ // delete element; // element = NULL; //} return destScalarType; } void esImageData::run() { loadPixelResult = false; int destScalarType = GetScalarType(); if (destScalarType == -1) return; loadPixelResult=LoadPixelData(tmpPixelData, pixelType); if (loadPixelResult) { int frameSize = m_Width * m_Height; switch (destScalarType) { vtkTemplateMacro( { VTK_TT*curFramePtr = (VTK_TT*) tmpPixelData; std::for_each(curFramePtr, curFramePtr + frameSize - 1, [&](VTK_TT &val) {val = val * m_RescaleSlope + m_RescaleIntercept; }); }); } } }
最新发布
09-03
#include "sys.h" IMU_DATA_t imu_data = { 0 }; //9轴数据值 ATTITUDE_DATA_t imu_attitude = { 0 }; //3轴姿态角 volatile uint8_t ADC_StartFlag = 0; volatile uint8_t BuzzerTipsTime = 0; //4路电机控制PWM值 volatile int MotorA=0,MotorB=0,MotorC=0,MotorD=0; //4路编码器值 volatile int EncoderA=0,EncoderB=0,EncoderC=0,EncoderD=0; //电机转速 volatile float MotorArpm = 0,MotorBrpm = 0,MotorCrpm = 0,MotorDrpm = 0; //电机目标转速 volatile float TargetArpm = 0,TargetBrpm = 0,TargetCrpm = 0,TargetDrpm = 0; //电池电压 float robotVol; //舵机目标角度 float target_angle = 90; //定义使用的舵机是180度还是270度舵机 #define _270_SERVO 0 #define _180_SERVO 1 //电机控制相关参数配置 #define MOTOR_REDUCTION_RATION 30 //电机减速比 #define ENCODER_ACCURACY 13 //编码器精度,GMR编码器是500,霍尔编码器是13 #define CONTROL_FREQ 100 //PID控制器的执行频率,也就是控制频率,跟中断配置相关,本例程配置的是200Hz //电机PI控制器参数 float Velocity_KP = 5.0f,Velocity_KI = 1.6f; char app_page1[256]={ 0 };//发送到APP首页的数据缓冲区 char app_page2[256]={ 0 };//发送到APP波形页面的数据缓冲区 char app_page3[256]={ 0 };//发送到APP参数页面的数据缓冲区 //测试数值,可以通过APP显示并修改 uint16_t TestAPP_Param1 = 100; uint16_t TestAPP_Param2 = 400; PIDController FollowPID_X,FollowPID_Y; static int servopwm = 1500; static short mycontrol = 0; typedef struct { uint8_t header; // 0xAA uint8_t x; // 水平坐标 (0-255) uint8_t y; // 俯仰坐标 (0-255) uint8_t footer; // 0x55 } UART_Coordinate_t; volatile UART_Coordinate_t uart_coord = {0};//定义一个坐标结构体变量 volatile uint8_t uart_rx_buffer[4] = {0}; volatile uint8_t uart_rx_index = 0; volatile uint8_t uart_coord_ready = 0;//坐标数据就绪标志 // 俯仰舵机PWM通道(新增) #define Servo_Pitch_PWM TIM13->CCR1 // 在main()函数中添加TIM13初始化(PWM频率50Hz) void TIM13_PWM_Init(uint32_t arr, uint32_t psc) { // 类似TIM12_SERVO_Init的实现,使用TIM13 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE); TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler = psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM13, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM13, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM13, ENABLE); TIM_Cmd(TIM13, ENABLE); } int main(void) { //设置系统中断优先级分组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //初始化SysTick,配置其频率为1000Hz SysTick_Init(1000); uart1_init(115200);//串口1初始化 uart2_init(9600); //串口2初始化,用于蓝牙APP LED_Init(); //LED初始化 OLED_Init(); //OLED初始化 TIM7_Init(83,4999);//开启定时器7中断,频率200HZ //ICM20948陀螺仪初始化(内部已包含软件iic初始化) pIMUInterface_t icm20948 = &UserICM20948; icm20948->Init(); Adc_Init(); //ADC初始化 KEY_Init(); //用户按键、使能开关初始化 Buzzer_Init();//蜂鸣器初始化 //4路电机PWM初始化,PWM频率10KHz.一路电机控制需要2路PWM //0-16799对应电机0到最大转速 负数时电机转向相反 TIM1_PWM_Init(16799,0); TIM9_PWM_Init(16799,0); TIM10_PWM_Init(16799,0); TIM11_PWM_Init(16799,0); //4路编码器初始化 Encoder_Init_TIM2(); Encoder_Init_TIM3(); Encoder_Init_TIM4(); Encoder_Init_TIM5(); //舵机PWM初始化,初始化为50Hz,0-19099对应 0 到 100% 空比 //2.5%~12.5%(对应数值500~2500)空比对应舵机的0-180或0-270度 TIM12_SERVO_Init(19999,83); TIM13_PWM_Init(19999, 83); // 新增:俯仰舵机(TIM13) PID_Init(&FollowPID_X,1.5,0,8);//PID控制器初始化 PID_Init(&FollowPID_Y,-0.024,-0,-0.04);//PID控制器初始化 while(1) { //电池电压采集 if( ADC_StartFlag==1 ) { ADC_StartFlag=0; robotVol = (float)Get_Adc(Battery_Ch)/4095.0f * 3.3f * 11.0f; } //显示AB电机以及舵机的目标值、实际值 OLED_ShowFloat(0,0,ObjectTrack.cam_centerX,4,2); OLED_ShowFloat(0,10,ObjectTrack.cam_centerY,4,2); OLED_ShowFloat(0,30,ObjectTrack.centerX,4,2);//水平 OLED_ShowFloat(0,40,ObjectTrack.centerY,4,2); OLED_ShowShortNum(0,50,mycontrol,4,12); //显示C30D供电电压 OLED_ShowFloat(60,50,robotVol,2,2); OLED_ShowString(108,50,"V"); OLED_Refresh_Gram(); } } // 新增:串口1接收中断处理函数(替换原有空函数或添加) void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); // 协议解析:0xAA开头,0x55结尾,4字节数据 if (uart_rx_index == 0 && data == 0xAA) { uart_rx_buffer[uart_rx_index++] = data; } else if (uart_rx_index > 0) { uart_rx_buffer[uart_rx_index++] = data; if (uart_rx_index >= 4) { if (uart_rx_buffer[3] == 0x55) { uart_coord.header = uart_rx_buffer[0]; uart_coord.x = uart_rx_buffer[1]; uart_coord.y = uart_rx_buffer[2]; uart_coord.footer = uart_rx_buffer[3]; uart_coord_ready = 1; // 标记数据就绪 } uart_rx_index = 0; } } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } } int servo_speed_control(int speed) { /* * 将输入速度(-350 to 350)映射到舵机PWM值(1000 to 2000),包含死区 * speed: 输入速度值,-350(最大逆时针) 到 350(最大顺时针),0为停止 * 死区: 速度-50到50对应PWM=1500(停止) * 返回: 对应的PWM值(1000-2000) */ // 限制输入范围 if (speed > 400) speed = 400; if (speed < -400) speed = -400; int pwm = 0; if( speed > 0 ) pwm = 1600 + speed; else if( speed < 0 ) pwm = 1400 + speed; else pwm = 1500; return pwm; } //定时器7更新中断服务函数,根据配置的运行频率触发 void TIM7_IRQHandler(void) { static uint32_t LedTickCnt = 0; static uint32_t adc_taskCnt = 0; static uint8_t EncoderTaskFlag = 0; static uint32_t mode = 1; uint32_t ticktime = 0; if(TIM_GetITStatus(TIM7, TIM_IT_Update)!=RESET) { TIM_ClearITPendingBit(TIM7, TIM_IT_Update); if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM7, TIM_IT_Update); // ... 原有电机控制、舵机控制代码 ... pIMUInterface_t icm20948 = &UserICM20948; //指定操作设备 icm20948->Update_9axisVal(&imu_data); //获取9轴数据值 icm20948->UpdateAttitude(imu_data,&imu_attitude); //根据9轴数据,计算出姿态角.当任务频率发生改变时,请更新 attitudeUpdate 函数内 halftime 变量 //LED闪烁,1秒闪烁1次.辅助检查频率是否正确 LedTickCnt++; if( LedTickCnt > 200 * 1 ) { LedTickCnt=0; LED = !LED; } //ADC任务 adc_taskCnt++; if( adc_taskCnt == 10 ) { adc_taskCnt = 0; ADC_StartFlag=1; } //1650-2000 //1350-1000 uint8_t keystate = KEY_Scan(200,0); if( keystate == long_click ) { //k210 mode=1; } else if( keystate == single_click ) { //正 mode=2; } else if( keystate == double_click ) { //正 mode=3; } if( mode==1 ) { mycontrol = PID_Update(&FollowPID_X,ObjectTrack.cam_centerX,ObjectTrack.centerX); // mycontrol=0; mycontrol -= imu_data.gyro.z * 57.3f * 1.4f; } else if( mode==2 ) { mycontrol = 100; } else if( mode==3 ) { mycontrol = -100; } } if (uart_coord_ready) //标志,0和1 { uart_coord_ready = 0; // 水平方向(360度速度控制):x坐标转速度(-350到350) int speed_yaw = (int)uart_coord.x - 128; // 映射到-128~127 speed_yaw = speed_yaw * 3; // 放大到-384~381(接近±350) speed_yaw = target_limit_int(speed_yaw, -350, 350); Servo_PWM = servo_speed_control(speed_yaw); // 水平舵机 // 俯仰方向(180度角度控制):y坐标转角度(0~180) float angle_pitch = (float)uart_coord.y * 180.0f / 255.0f; angle_pitch = target_limit_float(angle_pitch, 0, 180); Servo_Pitch_PWM = Angle_to_PWM(angle_pitch); // 俯仰舵机 } // ... 原有电机控制、舵机控制代码 ... // target_angle = PID_Update(&FollowPID_Y,ObjectTrack.cam_centerY,ObjectTrack.centerY); // // //舵机控制,限幅目标值 // #if _180_SERVO // target_angle = target_limit_float(target_angle,0,180); // #endif // // #if _270_SERVO // target_angle = target_limit_float(target_angle,0,270); // #endif //电机PWM限幅 mycontrol = target_limit_int(mycontrol,-400,400); MotorB = target_limit_int(MotorB,-6000,6000); MotorC = target_limit_int(MotorC,-6000,6000); MotorD = target_limit_int(MotorD,-6000,6000); //电机控制:发送PWM到电机 Set_Pwm(MotorA,MotorB,MotorC,MotorD); //舵机控制:将目标角度转换为PWM并赋值 // Servo_PWM = Angle_to_PWM(target_angle); Servo_PWM=servo_speed_control(mycontrol); } } //串口2接收中断,接收手机APP通过蓝牙模块发送过来的数据 void USART2_IRQHandler(void) { uint8_t Usart_Receive; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//判断是否接收到数据 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); Usart_Receive = USART_ReceiveData(USART2); K210_data_callback(Usart_Receive); } } //串口2发送函数,用于发送数据到APP void AppSendData(char* buffer,uint8_t Len) { for(uint8_t i=0;i<Len;i++) { while((USART2->SR&0X40)==0);//循环发送,直到发送完毕 USART2->DR = (u8) buffer[i]; } } //舵机角度转化为PWM函数 int Angle_to_PWM(float Angle) { //PWM 500~2500 对应空比 2.5%~12.5%,对应舵机 0-180度 #if _180_SERVO // 180度舵机角度转换 if (Angle < 0.0f) Angle = 0.0f; if (Angle > 180.0f) Angle = 180.0f; // 线性映射:PWM = 500 + (2500-500)*Angle/180 // 简化后:PWM = 500 + 2000*Angle/180 int PWM = (int)(500 + (2000.0f * Angle / 180.0f)); // 确保PWM值在有效范围内 if (PWM < 500) PWM = 500; if (PWM > 2500) PWM = 2500; return PWM; #endif //如果是270度舵机,则使用下面内容 #if _270_SERVO // 限制角度范围在0~270度 if (Angle < 0.0f) Angle = 0.0f; if (Angle > 270.0f) Angle = 270.0f; // 线性映射:PWM = 500 + (2500-500)*Angle/270 // 简化后:PWM = 500 + 2000*Angle/270 int PWM = (int)(500 + (2000.0f * Angle / 270.0f)); // 确保PWM值在有效范围内 if (PWM < 500) PWM = 500; if (PWM > 2500) PWM = 2500; return PWM; #endif } int target_limit_int(int insert,int low,int high) { if (insert < low) return low; else if (insert > high) return high; else return insert; } float target_limit_float(float insert,float low,float high) { if (insert < low) return low; else if (insert > high) return high; else return insert; } //PI控制器 int Incremental_PI_A (float Encoder,float Target) { static float Bias=0,Pwm=0,Last_bias=0; Bias=Target-Encoder; //Calculate the deviation //计算偏差 Pwm+=Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias; if(Pwm>16700)Pwm=16700; if(Pwm<-16700)Pwm=-16700; Last_bias=Bias; //Save the last deviation //保存上一次偏差 return Pwm; } int Incremental_PI_B (float Encoder,float Target) { static float Bias=0,Pwm=0,Last_bias=0; Bias=Target-Encoder; //Calculate the deviation //计算偏差 Pwm+=Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias; if(Pwm>16700)Pwm=16700; if(Pwm<-16700)Pwm=-16700; Last_bias=Bias; //Save the last deviation //保存上一次偏差 return Pwm; } int Incremental_PI_C (float Encoder,float Target) { static float Bias=0,Pwm=0,Last_bias=0; Bias=Target-Encoder; //Calculate the deviation //计算偏差 Pwm+=Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias; if(Pwm>16700)Pwm=16700; if(Pwm<-16700)Pwm=-16700; Last_bias=Bias; //Save the last deviation //保存上一次偏差 return Pwm; } int Incremental_PI_D (float Encoder,float Target) { static float Bias=0,Pwm=0,Last_bias=0; Bias=Target-Encoder; //Calculate the deviation //计算偏差 Pwm+=Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias; if(Pwm>16700)Pwm=16700; if(Pwm<-16700)Pwm=-16700; Last_bias=Bias; //Save the last deviation //保存上一次偏差 return Pwm; } int voltage_to_percentage(float voltage) { const float V_MIN = 9.5f; // 最小电压 (0%) const float V_MAX = 12.4f; // 最大电压 (100%) // 确保电压在有效范围内 if (voltage < V_MIN) return 0; if (voltage > V_MAX) return 100; // 线性插值计算百分比并取整 int percentage = (int)(((voltage - V_MIN) / (V_MAX - V_MIN)) * 100.0f + 0.5f); // 四舍五入 if( percentage > 100 ) percentage = 100; if( percentage <= 0 ) percentage = 0; return percentage; } PIDController FollowPID_X,FollowPID_Y; void PID_Init(PIDController *pid, double kp, double ki, double kd) { pid->kp = kp; pid->ki = ki; pid->kd = kd; pid->setpoint = 0; pid->integral = 0.0; pid->last_error = 0.0; pid->last_input = 0.0; } double PID_Update(PIDController *pid, double target , double input) { pid->setpoint = target; double error = pid->setpoint - input;//本次偏差 double derivative = (input - pid->last_input);//上一次偏差 pid->integral += error;//积分 // 计算PID输出 double output = pid->kp * error + pid->ki * pid->integral - pid->kd * derivative; // 更新上一次的误差和输入 pid->last_error = error; pid->last_input = input; return output; } 这个代码为什么无法实现串口通信
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值