file-type

MATLAB实现MSK调制解调技术的研究

版权申诉

RAR文件

3KB | 更新于2024-10-25 | 35 浏览量 | 0 下载量 举报 1 收藏
download 限时特惠:#14.90
MSK是一种连续相位调制技术,它在数字通信系统中广泛应用,特别是在移动通信和卫星通信领域。MSK的特点是其具有恒定的包络和最小的频率偏移,这使得它在功率放大器设计上更为高效,并且对相位噪声不敏感。该压缩文件可能包含实现MSK调制解调器所需的MATLAB脚本文件,例如.m文件,用于模拟或教学目的。 在MATLAB环境下,MSK调制器可以通过一系列的算法来实现,如先对输入的比特流进行差分编码,然后利用正弦波和余弦波进行调制。MSK调制的实现需要考虑到载波频率、比特率以及相位连续的特性。对于MSK接收端,通常包括一个匹配滤波器,用于优化信号的接收,并通过解调过程恢复出原始的比特流。 MSK在数字通信系统中的优势包括频谱效率高、抗干扰能力强以及解调过程相对简单。为了满足不同通信标准的需求,MSK的变体如高斯最小频移键控(GMSK)也被广泛使用。GMSK在MSK的基础上加入了高斯滤波器,以减少频谱扩展,提高信号的频谱效率。 该压缩文件可能提供了一套完整的MSK调制与解调的模拟环境,允许用户在MATLAB中对MSK信号进行生成、传输、接收和分析。这种模拟环境对于工程教育和研究工作都具有重要价值,可以帮助通信专业的学生和工程师更深入地理解MSK调制解调技术,掌握数字信号处理的核心概念。 对于标签中的'matlab_msk'和'msk_receiver',可以推断该压缩文件包含的是有关MSK调制和接收技术的MATLAB代码或脚本。'msk_msk_msk'可能是该资源的关键词或相关术语,暗示该文件主要围绕MSK技术进行开发和讨论。 在文件名称列表中仅有"MSK",说明该压缩文件是一个专门针对MSK技术的资源,可能只包含单一或少数几个文件。这表明用户下载并解压后,将直接面对与MSK技术相关的MATLAB脚本或项目文件,无需额外的文件搜索或识别过程。 综上所述,MSK.rar压缩文件是一个专门针对MSK调制和解调技术的MATLAB资源,它提供了一种模拟和实现MSK调制器与接收器的方式,可能包括了演示代码、函数脚本等,有助于用户在通信系统设计、仿真和研究中应用MSK技术。"

相关推荐

filetype

u8 OLED_GRAM[128][8]; /************************************************************************** Function: Refresh the OLED screen Input : none Output : none گ˽٦ŜúˢтOLEDǁĻ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void OLED_Refresh_Gram(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //Set page address (0~7) //ʨ׃ҳַ֘è0~7é OLED_WR_Byte (0x00,OLED_CMD); //Set the display location - column low address //ʨ׃Дʾλ׃j֍ַ֘ OLED_WR_Byte (0x10,OLED_CMD); //Set the display location - column height address //ʨ׃Дʾλ׃jַٟ֘ for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } } void OLED_Refresh_Line(void) { u8 i,n; for(i=0;i<2;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //Set page address (0~7) //ʨ׃ҳַ֘è0~7é OLED_WR_Byte (0x00,OLED_CMD); //Set the display location - column low address //ʨ׃Дʾλ׃j֍ַ֘ OLED_WR_Byte (0x10,OLED_CMD); //Set the display location - column height address //ʨ׃Дʾλ׃jַٟ֘ for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } } /************************************************************************** Function: Refresh the OLED screen Input : Dat: data/command to write, CMD: data/command flag 0, represents the command;1, represents data Output : none گ˽٦ŜúвOLEDдɫһٶؖޚ ɫࠚӎ˽údat:Ҫдɫք˽ߝ/ļ®ìcmd:˽ߝ/ļ®Ҫ־ 0,ҭʾļ®;1,ҭʾ˽ߝ ׵ܘ ֵúϞ **************************************************************************/ void OLED_WR_Byte(u8 dat,u8 cmd) { u8 i; if(cmd) OLED_RS_Set(); else OLED_RS_Clr(); for(i=0;i<8;i++) { OLED_SCLK_Clr(); if(dat&0x80) OLED_SDIN_Set(); else OLED_SDIN_Clr(); OLED_SCLK_Set(); dat<<=1; } OLED_RS_Set(); } /************************************************************************** Function: Turn on the OLED display Input : none Output : none گ˽٦ŜúߪǴOLEDДʾ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void OLED_Display_On(void) { OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC command //SET DCDCļ® OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON } /************************************************************************** Function: Turn off the OLED display Input : none Output : none گ˽٦ŜúژҕOLEDДʾ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void OLED_Display_Off(void) { OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC command //SET DCDCļ® OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF } /************************************************************************** Function: Screen clear function, clear the screen, the entire screen is black, and did not light up the same Input : none Output : none گ˽٦Ŝúȥǁگ˽,ȥΪǁ,ֻٶǁώۚɫքìۍû֣һҹ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00; OLED_Refresh_Gram(); //Update the display //ټтДʾ } /************************************************************************** Function: Draw point Input : x,y: starting coordinate;T :1, fill,0, empty Output : none گ˽٦Ŝúۭ֣ ɫࠚӎ˽úx,y :ǰ֣ظҪ; t:1,ͮԤ,0,ȥࠕ ׵ܘ ֵúϞ **************************************************************************/ void OLED_DrawPoint(u8 x,u8 y,u8 t) { u8 pos,bx,temp=0; if(x>127||y>63)return;//ӬԶ׶Χ‹. pos=7-y/8; bx=y%8; temp=1<<(7-bx); if(t)OLED_GRAM[x][pos]|=temp; else OLED_GRAM[x][pos]&=~temp; } /************************************************************************** Function: Displays a character, including partial characters, at the specified position Input : x,y: starting coordinate;Len: The number of digits;Size: font size;Mode :0, anti-white display,1, normal display Output : none گ˽٦Ŝú՚ָ֨λ׃Дʾһٶؖػ,Ѽ(ҿؖؖػ ɫࠚӎ˽úx,y :ǰ֣ظҪ; len :˽ؖքλ˽; size:ؖͥճС; mode:0,״їДʾ,1,ֽӣДʾ ׵ܘ ֵúϞ **************************************************************************/ void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode) { u8 temp,t,t1; u8 y0=y; chr=chr-' '; //Get the offset value //փսƫӆ۳քֵ for(t=0;t<size;t++) { if(size==12)temp=oled_asc2_1206[chr][t]; //Invoke 1206 font //ַԃ1206ؖͥ else temp=oled_asc2_1608[chr][t]; //Invoke the 1608 font //ַԃ1608ؖͥ for(t1=0;t1<8;t1++) { if(temp&0x80)OLED_DrawPoint(x,y,mode); else OLED_DrawPoint(x,y,!mode); temp<<=1; y++; if((y-y0)==size) { y=y0; x++; break; } } } } /************************************************************************** Function: Find m to the NTH power Input : m: base number, n: power number Output : none گ˽٦ŜúȳmքnՎ׽քگ˽ ɫࠚӎ˽úmú֗˽ìnúՎ׽˽ ׵ܘ ֵúϞ **************************************************************************/ u32 oled_pow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } /************************************************************************** Function: Displays 2 numbers Input : x,y: starting coordinate;Len: The number of digits;Size: font size;Mode: mode, 0, fill mode, 1, overlay mode;Num: value (0 ~ 4294967295); Output : none گ˽٦ŜúДʾ2ٶ˽ؖ ɫࠚӎ˽úx,y :ǰ֣ظҪ; len :˽ؖքλ˽; size:ؖͥճС; mode:ģʽ, 0,ͮԤģʽ, 1,־ݓģʽ; num:˽ֵ(0~4294967295); ׵ܘ ֵúϞ **************************************************************************/ void OLED_ShowNumber(u8 x,u8 y,u32 num,u8 len,u8 size) { u8 t,temp; u8 enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size/2)*t,y,' ',size,1); continue; }else enshow=1; } OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1); } } /************************************************************************** Function: Display string Input : x,y: starting coordinate;*p: starting address of the string Output : none گ˽٦ŜúДʾؖػԮ ɫࠚӎ˽úx,y :ǰ֣ظҪ; *p:ؖػԮǰʼַ֘ ׵ܘ ֵúϞ **************************************************************************/ void OLED_ShowString(u8 x,u8 y,const u8 *p) { #define MAX_CHAR_POSX 122 #define MAX_CHAR_POSY 58 while(*p!='\0') { if(x>MAX_CHAR_POSX){x=0;y+=16;} if(y>MAX_CHAR_POSY){y=x=0;OLED_Clear();} OLED_ShowChar(x,y,*p,12,1); x+=8; p++; } } void OLED_ShowString16(u8 x,u8 y,const u8 *p) { #define MAX_CHAR_POSX 122 #define MAX_CHAR_POSY 58 while(*p!='\0') { if(x>MAX_CHAR_POSX){x=0;y+=16;} if(y>MAX_CHAR_POSY){y=x=0;OLED_Clear();} OLED_ShowChar(x,y,*p,16,1); x+=8; p++; } } /************************************************************************** Function: Initialize the OLED Input : none Output : none گ˽٦ŜúԵʼۯOLED ɫࠚӎ˽: Ϟ ׵ܘ ֵúϞ **************************************************************************/ void OLED_Init(void) { // 1. 关闭显示 OLED_WR_Byte(0xAE, OLED_CMD); // 2. 硬件复位 OLED_RST_Clr(); delay_ms(10); OLED_RST_Set(); delay_ms(50); // 3. 重新配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &GPIO_InitStructure); // 4. 精简初始化序列 const uint8_t init_seq[] = { 0xAE, // 关闭显示 0xD5, 0x80, // 时钟分频 0xA8, 0x3F, // 多路复用 0xD3, 0x00, // 显示偏移 0x40, // 起始行 0x8D, 0x14, // 开启充电泵 0x20, 0x02, // 页地址模式 0xA1, // 段重定向 0xC8, // COM扫描方向 0xDA, 0x12, // COM配置 0x81, 0xEF, // 对比度 0xD9, 0xF1, // 预充电 0xDB, 0x30, // VCOMH 0xA4, // 关闭全局显示 0xA6 // 正常显示模式 }; // 直接发送所有命令(无错误检查) for(uint8_t i=0; i<sizeof(init_seq); ) { OLED_WR_Byte(init_seq[i++], OLED_CMD); // 保留关键命令的固定延时结构(但移除条件判断) if(i==7 || i==9 || i==11) delay_ms(10); } // 5. 清屏并开启显示 OLED_Clear(); OLED_WR_Byte(0xAF, OLED_CMD); }#define SDA_IN() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=0<<11*2;} //PB5ˤɫģʽ #define SDA_OUT() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB5ˤԶģʽ //IOәطگ˽ #define IIC_SCL PBout(10) //SCL #define IIC_SDA PBout(11) //SDA #define READ_SDA PBin(11) //ˤɫSDA #ifndef I2C_Direction_Transmitter #define I2C_Direction_Transmitter ((uint8_t)0x00) #endif #ifndef I2C_Direction_Receiver #define I2C_Direction_Receiver ((uint8_t)0x01) #endif enum { I2C_ACK, I2C_NACK };void I2C_GPIOInit(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ʹŜGPIOBʱד GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ǕͨˤԶģʽ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//ΆάˤԶ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ʏ- GPIO_Init(GPIOB, &GPIO_InitStructure);//Եʼۯ IIC_SCL=1; IIC_SDA=1; } /************************************************************************** Function: Simulate IIC start signal Input : none Output : none گ˽٦ŜúģŢIICǰʼхۅ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void I2C_Start(void) { SDA_OUT(); //sdaПˤԶ IIC_SDA=1; if(!READ_SDA)return ; IIC_SCL=1; delay_us(1); IIC_SDA=0;//START:when CLK is high,DATA change form high to low if(READ_SDA)return ; delay_us(1); IIC_SCL=0;//ǯסI2C؜Пì׼Ѹע̍ܲޓ˕˽ߝ return ; } /************************************************************************** Function: Analog IIC end signal Input : none Output : none گ˽٦ŜúģŢIICޡ˸хۅ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void I2C_Stop(void) { SDA_OUT();//sdaПˤԶ IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(1); IIC_SCL=1; IIC_SDA=1;//ע̍I2C؜Пޡ˸хۅ delay_us(1); } bool I2C_WaiteForAck(void) { u8 ucErrTime=0; SDA_IN(); //SDAʨ׃Ϊˤɫ IIC_SDA=1; delay_us(1); IIC_SCL=1; delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>50) { I2C_Stop(); return 0; } delay_us(1); } IIC_SCL=0;//ʱדˤԶ0 return 1; } /************************************************************************** Function: IIC response Input : none Output : none گ˽٦ŜúIICӦհ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void I2C_Ack(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(1); IIC_SCL=1; delay_us(1); IIC_SCL=0; } /************************************************************************** Function: IIC don't reply Input : none Output : none گ˽٦ŜúIICһӦհ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void I2C_NAck(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(1); IIC_SCL=1; delay_us(1); IIC_SCL=0; } bool I2C_WriteOneBit(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitNum, uint8_t Data) { uint8_t Dat; Dat =I2C_ReadOneByte(DevAddr, RegAddr); Dat = (Data != 0) ? (Dat | (1 << BitNum)) : (Dat & ~(1 << BitNum)); I2C_WriteOneByte(DevAddr, RegAddr, Dat); return true; } bool I2C_WriteBits(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitStart, uint8_t Length, uint8_t Data) { uint8_t Dat, Mask; Dat = I2C_ReadOneByte(DevAddr, RegAddr); Mask = (0xFF << (BitStart + 1)) | 0xFF >> ((8 - BitStart) + Length - 1); Data <<= (8 - Length); Data >>= (7 - BitStart); Dat &= Mask; Dat |= Data; I2C_WriteOneByte(DevAddr, RegAddr, Dat); return true; } /************************************************************************** Function: IIC sends a bit Input : none Output : none گ˽٦ŜúIICע̍һٶλ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ void I2C_WriteByte(uint8_t Data) { u8 t; SDA_OUT(); IIC_SCL=0;//-֍ʱדߪʼ˽ߝԫˤ for(t=0;t<8;t++) { IIC_SDA=(Data&0x80)>>7; Data<<=1; delay_us(1); IIC_SCL=1; delay_us(1); IIC_SCL=0; delay_us(1); } } u8 I2C_WriteOneByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data) { I2C_Start(); I2C_WriteByte(DevAddr | I2C_Direction_Transmitter); I2C_WaiteForAck(); I2C_WriteByte(RegAddr); I2C_WaiteForAck(); I2C_WriteByte(Data); I2C_WaiteForAck(); I2C_Stop(); return 1; } bool I2C_WriteBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff) { uint8_t i; if(0 == Num || NULL == pBuff) { return false; } I2C_Start(); I2C_WriteByte(DevAddr | I2C_Direction_Transmitter); I2C_WaiteForAck(); I2C_WriteByte(RegAddr); I2C_WaiteForAck(); for(i = 0; i < Num; i ++) { I2C_WriteByte(*(pBuff + i)); I2C_WaiteForAck(); } I2C_Stop(); return true; } /************************************************************************** Function: IIC reads a bit Input : none Output : none گ˽٦ŜúIICׁȡһٶλ ɫࠚӎ˽úϞ ׵ܘ ֵúϞ **************************************************************************/ uint8_t I2C_ReadByte(uint8_t Ack) { uint8_t i, RecDat = 0; SDA_IN(); for(i = 0; i < 8; i ++) { // I2C_SCL_Clr(); IIC_SCL=0; delay_us(1); // I2C_SCL_Set(); IIC_SCL=1; RecDat <<= 1; if(READ_SDA) RecDat |= 0x01; else RecDat &= ~0x01; delay_us(1); } if(I2C_ACK == Ack) I2C_Ack(); else I2C_NAck(); return RecDat; } uint8_t I2C_ReadOneByte(uint8_t DevAddr, uint8_t RegAddr) { uint8_t TempVal = 0; I2C_Start(); I2C_WriteByte(DevAddr | I2C_Direction_Transmitter); I2C_WaiteForAck(); I2C_WriteByte(RegAddr); I2C_WaiteForAck(); I2C_Start(); I2C_WriteByte(DevAddr | I2C_Direction_Receiver); I2C_WaiteForAck(); TempVal = I2C_ReadByte(I2C_NACK); I2C_Stop(); return TempVal; } bool I2C_ReadBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff) { uint8_t i; if(0 == Num || NULL == pBuff) { return false; } I2C_Start(); I2C_WriteByte(DevAddr | I2C_Direction_Transmitter); I2C_WaiteForAck(); I2C_WriteByte(RegAddr); I2C_WaiteForAck(); I2C_Start(); I2C_WriteByte(DevAddr | I2C_Direction_Receiver); I2C_WaiteForAck(); for(i = 0; i < Num; i ++) { if((Num - 1) == i) { *(pBuff + i) = I2C_ReadByte(I2C_NACK); } else { *(pBuff + i) = I2C_ReadByte(I2C_ACK); } } I2C_Stop(); return true; }重写基于STM32F407的6针OLED 初始化