powerdesigner的一些技巧

本文介绍 PowerDesigner 在数据库设计过程中的实用技巧,包括调整检查规则、去除 SQL 语句中的引号、解决字段长度限制等问题,并提供批量生成测试数据的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

powerdesigner的一些技巧

http://anforen.5d6d.com/

先说下自己的发现: 

刚用powerdesigner有许多基本使用上的问题, 比如表和字段长度不能稍微长点, 导出时候报warning说表没有index或没有被引用。 后来发现这些都是check model在起作用, 调整一下check model对各种对象的check 规则就能解决以上问题, 比如关闭长度的检查,去掉对表index和引用的warn级别检查(warn只会提示一下, error的就会判定为check失败)。 

关闭check model又是过于极端的做法, 不太合适, 自己检查还是不如机器检查来的快和全面。 

 

 

sql语句中表名与字段名前的引号去除: 

 

打开cdm的情况下,进入Tools-Model Options-Naming Convention,把Name和Code的标签的Charcter case选项设置成Uppercase或者Lowercase,只要不是Mixed Case就行! 

或者选择Database->Edit current database->Script->Sql->Format,有一项CaseSensitivityUsingQuote,它的 comment为“Determines if the case sensitivity for identifiers is managed using double quotes”,表示是否适用双引号来规定标识符的大小写,可以看到右边的values默认值为“YES”,改为“No”即可! 

或者在打开pdm的情况下,进入Tools-Model Options-Naming Convention,把Name和Code的标签的Charcter case选项设置成Uppercase就可以! 

 

在修改name的时候,code的值将跟着变动,很不方便 

 

修改方法:PowerDesign中的选项菜单里修改,在[Tool]-->[General Options]->[Dialog]->[Operating modes]->[Name to Code mirroring],这里默认是让名称和代码同步,将前面的复选框去掉就行了。 

 

 

 

由pdm生成建表脚本时,字段超过15字符就发生错误(oracle) 

 

  原因未知,解决办法是打开PDM后,会出现Database的菜单栏,进入Database - Edit Current DBMS -script-objects-column-maxlen,把value值调大(原为30),比如改成60。出现表或者其它对象的长度也有这种错误的话都可以选择对应的objects照此种方法更改! 

或者使用下面的这种方法: 

     生成建表脚本时会弹出Database generation提示框:把options - check model的小勾给去掉,就是不进行检查(不推荐)! 

    或者可以修改C:/Program Files/Sybase/PowerDesigner Trial 11/Resource Files/DBMS/oracl9i2.xdb文件 

     修改好后,再cdm转为pdm时,选择“Copy the DBMS definition in model”把把这个资源文件拷贝到模型中。 

 

 

 

由CDM生成PDM时,自动生成的外键的重命名 

 

PDM Generation Options->Detail->FK index names默认是%REFR%_FK,改为FK_%REFRCODE%,其中%REFRCODE%指的就是CDM中Relationship的code!另外自动生成的父字段的规则是PDM Generation Options->Detail->FK column name template中设置的,默认是%.3:PARENT%_%COLUMN%,可以改为Par%COLUMN%表示是父字段! 

 

 

 

建立一个表后,为何检测出现Existence of index的警告 

    A table should contain at least one column, one index, one key, and one reference. 

可以不检查 Existence of index 这项,也就没有这个警告错误了! 

意思是说没有给表建立索引,而一个表一般至少要有一个索引,这是一个警告,不用管也没有关系! 

 

 

 

如何防止一对一的关系生成两个引用(外键) 

要定义关系的支配方向,占支配地位的实体(有D标志)变为父表。 

在cdm中双击一对一关系->Detail->Dominant role选择支配关系 

 

 

 

修改报表模板中一些术语的定义 

即文件:C:/Program Files/Sybase/PowerDesigner Trial 11/Resource Files/Report Languages/Chinese.xrl 

Tools-Resources-Report Languages-选择Chinese-单击Properties或双击目标 

修改某些对象的名称:Object Attributes/Physical Data Model/Column/ 

        ForeignKey:外键 

        Mandatory:为空 

        Primary:主键 

        Table:表 

用查找替换,把“表格”替换成“表” 

修改显示的内容为别的:Values Mapping/Lists/Standard,添加TRUE的转化列为是,FALSE的转化列为空 

另外Report-Title Page里可以设置标题信息 

 

 

 

PowerDesigner11中批量根据对象的name生成comment的脚本 

 

'****************************************************************************** 

'* File:     name2comment.vbs 

'* Purpose:  Database generation cannot use object names anymore 

'            in version 7 and above. 

'            It always uses the object codes. 

'            In case the object codes are not aligned with your 

'            object names in your model, this script will copy 

'            the object Name onto the object comment for 

'            the Tables and Columns. 

'* Title:    把对象name拷入comment属性中 

'* Version:  1.0 

'* Author: 

'* 执行方法:PD11 -- Open PDM -- Tools --  Execute Commands -- Run Script 

'****************************************************************************** 

 

Option Explicit 

ValidationMode = True 

InteractiveMode = im_Batch 

 

Dim mdl ' the current model 

 

' get the current active model 

Set mdl = ActiveModel 

If (mdl Is Nothing) Then 

   MsgBox "There is no current Model" 

ElseIf Not mdl.IsKindOf(PdPDM.cls_Model) Then 

   MsgBox "The current model is not an Physical Data model." 

Else 

   ProcessFolder mdl 

End If 

 

' This routine copy name into code for each table, each column and each view 

' of the current folder 

Private sub ProcessFolder(folder) 

   Dim Tab 'running  table 

   for each Tab in folder.tables 

      if not tab.isShortcut then 

         tab.comment = tab.name 

         Dim col ' running column 

         for each col in tab.columns 

            col.comment= col.name 

         next 

      end if 

   next 

 

   Dim view 'running view 

   for each view in folder.Views 

      if not view.isShortcut then 

         view.comment = view.name 

      end if 

   next 

 

   ' go into the sub-packages 

   Dim f ' running folder 

   For Each f In folder.Packages 

      if not f.IsShortcut then 

         ProcessFolder f 

      end if 

   Next 

end sub 

 

 

 

PowerDesigner 生成SQL的Existence of refernce错误问题 

现象:用PowerDesigner生成SQL语句时,提示Existence of refernce错误。 

原因:该表没有与其他表的关联(如外键等),而PowerDesigner需要存在一个refernce才能生成SQL. 

解决方法: 

    在工具栏空白处右键打开Palette面板,选中Link/Extended Dependency 按钮,然后在提示出错的表上添加到自己的Dependency。 

    重新生成SQL,你将发现刚才提示的错误没有了,问题解决。 

 

利用PowerDesigner批量生成测试数据 

主要解决方法: 

A:在PowerDesigner 建表 

B:然后给每一个表的字段建立相应的摘要文件 

步骤如下: 

Model->Test Data Profiles配置每一个字段摘要文件General:输入Name、Code、 

选择Class(数字、字符、时间)类型 

选择Generation Source: Automatic、List、ODBC、File Detail:配置字段相关信息 

所有字段摘要文件配置完成后双击该表->选择字段->Detail->选择Test Data Parameters 摘要文件如果字段值与其它字段有关系在: Computed Expression 中输入计算列--生成测试数据: 

DataBase->Generation Test Data-> 

选择:Genration 类型(Sript、ODBC) 

     Selection(选择要生成的表) 

     Test Data Genration(Default number of rows 生成记录行数)

http://anforen.5d6d.com/

#include<reg51.h> #include<intrins.h> #define dm P0 #define uchar unsigned char #define uint unsigned int sbit DQ = P1^6; sbit A0 = P2^2; sbit A1 = P2^3; sbit A2 = P2^4; int temp1 = 0; uint h; uint temp; uchar r; uchar code ditab[16] = { 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04, 0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 }; uchar code table_dm[12] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x00,0x40 }; uchar code table_dm1[] = { 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef }; uchar data temp_data[2] = {0x00, 0x00}; uchar data display[5] = {0x00,0x00,0x00,0x00,0x00}; /*************** ÑÓʱ ***************/ void delay(uint t) { for(; t > 0; t--); } /*************** λѡ ***************/ void select_digit(uchar digit) { A0 = digit & 0x01; A1 = (digit >> 1) & 0x01; A2 = (digit >> 2) & 0x01; } /************** ÏÔʾ **************/ void xianshi() { uchar i; for(i = 0; i < 4; i++) { select_digit(i); switch(i) { case 0: dm = table_dm[display[0]]; delay(300); break; case 1: dm = table_dm1[display[1]]; delay(300); break; case 2: dm = table_dm[display[2]]; delay(300); break; case 3: dm = table_dm[display[3]]; delay(300); break; } dm = 0x00; } } /************** ³õʼ»¯ **************/ bit ow_reset(void) { bit presence; DQ = 0; delay(50); DQ = 1; delay(6); presence = DQ; delay(45); return !presence; } /*************** ÃüÁÊý ***************/ void write_byte(uchar val) { uchar i; for(i = 0; i < 8; i++) { DQ = 0; _nop_();_nop_(); DQ = val & 0x01; delay(6); DQ = 1; val >>= 1; _nop_();_nop_(); } } uchar read_byte(void) { uchar i, value = 0; for(i = 0; i < 8; i++) { DQ = 0; _nop_();_nop_(); DQ = 1; _nop_();_nop_(); value >>= 1; if(DQ) value |= 0x80; delay(6); } return value; } /*************** ¶ÁζÈ***************/ uint read_temp() { ow_reset(); write_byte(0xCC); write_byte(0x44); delay(75000); ow_reset(); write_byte(0xCC); write_byte(0xBE); temp_data[0] = read_byte(); temp_data[1] = read_byte(); temp = temp_data[1]; temp <<= 8; temp |= temp_data[0]; return temp; } /*************** ζÈÊý¾Ý´¦Àí ***************/ bit work_temp(uint tem) { bit negative = 0; if(tem & 0x8000) { tem = ~tem + 1; negative = 1; } uchar fractional = tem & 0x0F; display[0] = ditab[fractional]; tem >>= 4; display[3] = tem / 100; display[2] = (tem % 100) / 10; display[1] = tem % 10; r = display[1] + display[2]*10 + display[3]*100; if(display[3] == 0) { display[3] = 10; if(display[2] == 0) { display[2] = 10; } } if(negative) { display[3] = 11; } return negative; } /*************** Ö÷º¯Êý ***************/ void main() { dm = 0x00; display[0] = 0; display[1] = 0; display[2] = 0; display[3] = 10; ow_reset(); write_byte(0xCC); write_byte(0x44); while(1) { work_temp(read_temp()); xianshi(); } }检查温度数据处理模块中的错误
最新发布
06-21
<think>我们正在处理一个关于DS18B20温度传感器在C语言程序中可能出现的错误的问题。用户提到了温度数据处理模块,包括温度读取、数值转换和显示部分。根据引用内容,我们知道DS18B20的温度数据是16位补码格式,并且需要根据分辨率调整小数部分。同时,引用[2]提到负温度的处理需要减1后取反(实际上是补码转原码的标准做法:取反加1,但这里说减1后取反,可能是笔误,因为补码转原码的正确步骤是:如果符号位为1,则数值部分取反加1)。常见的错误点:1.读取两个字节的顺序(DS18B20的数据是先低字节后高字节)。2.没有正确处理负温度(补码转换)。3.分辨率调整(默认是12位,即0.0625的倍数,但用户可能设置其他分辨率,不过通常我们按12位处理)。根据引用[1]和[2],我们总结转换步骤:a.读取两个字节(假设为byte0和byte1),组合成一个16位整数:temp=(byte1<<8)|byte0;注意:byte1是高字节,byte0是低字节。b.判断符号:如果temp的最高位(bit15)为1,则为负数,需要转换(补码转原码);否则为正数。c.负数的转换:取反加1(或者先减1再取反?引用[2]说减1后取反,但标准补码转原码是取反加1。实际上,对于负数,我们可以先取反再加1,或者先加1再取反?这里需要验证。实际上,标准做法是:数值部分取反加1,即对补码的数值部分取反加1(包括符号位不变?不对,补码转原码是:符号位不变,数值部分取反加1。但注意,我们这里得到的是补码形式的整数,在计算机中,负数的补码就是其表示形式,要得到原码的数值,我们可以直接使用有符号整数,或者进行转换。实际上,更简单的方法是将这个16位数视为有符号整数(int16_t),然后乘以分辨率(0.0625)即可。但要注意,在嵌入式系统中,我们可能没有int16_t,或者需要手动转换。然而,引用[2]提到他们最初的处理是“对负温度加1后取反”出错,后来改为“减1后取反”。这可能是他们代码中的具体实现,但标准做法应该是:-如果是负数(符号位为1),则先取反(整个16位,包括符号位?)再加1?不对,这样会改变符号位。实际上,补码转原码是:符号位不变,数值部分取反加1。因此,我们可以这样处理:temp=(byte1<<8)|byte0;if(temp&0x8000){//负数temp=~temp+1;//这样得到的是绝对值?不对,这样操作后得到的是其绝对值的二进制表示吗?实际上,对于16位补码,取反加1得到的是其绝对值(但符号位也会取反,所以这样操作后整个数变成了正数?)。实际上,这个操作就是求补码的相反数(即绝对值)。所以,我们可以直接使用://然后我们记住符号,最后加上负号。sign=-1;temp=temp&0x7FFF;//去掉符号位?不,上面的取反加1已经将整个数变成了正数(因为补码的负数取反加1就是其绝对值)。但是注意,取反加1后,符号位也取反了,所以变成了正数。所以,我们不需要再与0x7FFF,因为取反加1后,符号位变成了0。//但是,还有一种做法:不改变temp,而是将其视为有符号整数,然后直接转换为浮点数,再乘以0.0625。}实际上,更简单且不易出错的方法是使用有符号整数:int16_traw=(byte1<<8)|byte0;//这样,如果byte1的最高位是1,则raw就是负数。floattemperature=raw*0.0625f;但是,在嵌入式系统中,有时为了避免浮点数运算,我们会将温度值用整数表示(例如,将温度值乘以1000,用毫度表示)。因此,我们检查代码时,重点检查:1.两个字节的读取顺序和组合(byte1左移8位与byte0组合)。2.是否使用了有符号整数来解析温度值?或者手动处理了负温度?3.分辨率调整(乘以0.0625,或者除以16,因为16=2^4,对应12位分辨率下的4位小数)。另外,引用[3]中显示的温度值有三位小数,但实际上DS18B20的分辨率是0.0625(即1/16),所以小数部分应该是0.0625的倍数,最多四位小数,但通常显示时取三位或两位。例如:25.625、25.750等。现在,假设用户提供了一段代码,我们需要检查其中可能的错误。由于用户没有提供具体代码,我们将列出常见错误并给出正确代码示例。常见错误:1.字节顺序错误:将高字节和低字节组合时弄反。2.负温度处理错误:没有正确处理补码,导致负温度显示错误。3.浮点运算在嵌入式系统中可能不希望使用(但用户显示中使用了浮点数,所以如果用户使用了浮点数,则没问题)。4.没有根据实际分辨率调整(但通常默认12位,所以乘以0.0625即可)。正确转换的示例代码:方法1:使用有符号整数(推荐)```c#include<stdint.h>//为了使用int16_t//假设从DS18B20读取两个字节,low_byte是低字节,high_byte是高字节uint8_tlow_byte=...;//读取的低字节uint8_thigh_byte=...;//读取的高字节//组合成16位有符号整数int16_traw_temp=(high_byte<<8)|low_byte;//转换为温度值(摄氏度)floattemperature=raw_temp*0.0625f;//然后显示温度printf("Temperature:%.3fC\n",temperature);//显示三位小数```方法2:手动处理负温度(不使用有符号整数类型)```cuint8_tlow_byte=...;uint8_thigh_byte=...;uint16_traw=(high_byte<<8)|low_byte;floattemperature;//判断是否为负数(最高位为1)if(raw&0x8000){//如果是负数,则取反加1,得到绝对值的二进制表示(注意:这样操作后,raw变成了正数)raw=~raw+1;temperature=raw*0.0625f;temperature=-temperature;//加上负号}else{temperature=raw*0.0625f;}```注意:方法2中,取反加1后,raw变成了一个正数,然后乘以0.0625得到正值,再取负。但是,引用[2]提到他们使用“减1后取反”解决了问题,这与我们通常的“取反加1”相反。这可能是他们代码中实现的一个特例?或者他们描述有误?实际上,对于补码,负数的转换应该是取反加1(得到其绝对值)。而“减1后取反”是另一种操作,我们来看:假设一个负数补码为N,则其绝对值应该是:~N+1(取反加1)。而“减1后取反”是:先减1,再取反,即~(N-1)。根据补码的性质,这等价于取反加1?我们来验证:取反加1:~N+1减1后取反:~(N-1)=~N+1(因为~(N-1)=~N+1,这是二进制运算的性质:取反相当于用全1减,所以~(N-1)=0xFFFF-(N-1)=0xFFFF-N+1=(~N)+1)所以,实际上,~(N-1)等于~N+1。也就是说,这两种操作是等价的。因此,用户引用[2]中提到的“减1后取反”实际上和“取反加1”是同样的效果。所以两种方法都可以。因此,在方法2中,我们也可以这样写:```cif(raw&0x8000){raw=raw-1;raw=~raw;temperature=raw*0.0625f;temperature=-temperature;}```但注意,这样写的话,raw先减1,再取反,然后得到的是绝对值(正数),然后再取负。所以,无论使用哪种方法,只要正确转换即可。现在,我们回到用户的问题:检查代码中的错误。我们需要用户提供他们的代码,但用户没有提供。因此,我们只能列举常见错误和修正方法。常见错误1:字节顺序错误错误代码:raw=(low_byte<<8)|high_byte;//这样组合是错误的,因为DS18B20是先发送低字节,后发送高字节。常见错误2:负温度处理遗漏错误代码:直接使用raw(无符号整数)乘以0.0625,这样负温度会被解释为正数(因为无符号整数会忽略符号位)。常见错误3:负温度转换错误错误代码:在负温度时,只进行了取反,没有加1(或没有减1再取反),导致绝对值错误。常见错误4:分辨率处理错误,例如除以16而不是乘以0.0625(两者等价),但有时可能用整数除法导致精度丢失。常见错误5:显示格式错误,比如没有正确格式化浮点数(显示整数部分和小数部分)。另外,在显示部分,引用[3]中使用了OLED显示,并调整字体和位置,这属于显示代码,如果显示不正常,可能是显示驱动的问题,但用户的问题集中在温度数据处理模块。因此,我们建议用户检查上述常见错误,并提供代码以便进一步分析。如果没有代码,我们可以给出一个参考实现,并建议用户对照。参考实现(使用有符号整数,避免手动转换):```c//读取DS18B20温度值并转换为浮点数floatread_ds18b20_temperature(){uint8_tlow_byte=read_byte();//从DS18B20读取低字节uint8_thigh_byte=read_byte();//读取高字节int16_traw=(high_byte<<8)|low_byte;returnraw*0.0625f;}```如果用户使用的编译器不支持int16_t(或者没有stdint.h),则可以使用手动转换:```cfloatread_ds18b20_temperature(){uint8_tlow_byte=read_byte();uint8_thigh_byte=read_byte();uint16_traw=(high_byte<<8)|low_byte;floattemp;if(raw&0x8000){//处理负温度raw=~raw+1;//取反加1,得到绝对值(正数)temp=raw*0.0625f;temp=-temp;}else{temp=raw*0.0625f;}returntemp;}```或者使用减1取反:```cif(raw&0x8000){raw=raw-1;raw=~raw;temp=raw*0.0625f;temp=-temp;}```最后,关于显示部分,用户需要确保将浮点数正确格式化为字符串。例如,在OLED上显示,可能需要将浮点数转换为字符串,然后显示。如果显示乱码,可能是显示驱动的问题,而不是温度转换的问题。如果用户遇到负温度显示不正确(例如显示正数),那么一定是负温度处理部分有错误。如果温度值明显不对(比如数值很大),可能是字节顺序错误。建议用户检查他们的代码,对照上述参考实现。如果用户提供了具体代码,我们可以进一步分析。相关问题:1.DS18B20温度转换中,如何避免浮点数运算而使用整数运算?2.DS18B20的分辨率设置如何影响温度转换?3.如何验证DS18B20温度读取的正确性?</think>### DS18B20温度数据处理模块错误检查与修正 在DS18B20温度数据处理模块中,常见错误主要集中在温度读取、补码转换和显示实现三个环节。以下是关键错误点及修正方案: --- ### 一、常见错误及修正方案 #### 1. **温度读取错误** - **错误表现**: 未正确处理高低字节顺序或读取时序错误,导致原始数据错误。 - **修正代码**: ```c // 正确读取两个字节(低字节在前,高字节在后) uint8_t lsb = read_byte(); // 温度值低字节 uint8_t msb = read_byte(); // 温度值高字节 int16_t raw_temp = (msb << 8) | lsb; // 组合为16位数据 ``` #### 2. **补码转换错误** - **错误表现**: 负温度处理逻辑错误(如误用"加1取反"而非"减1取反")[^2]。 - **修正逻辑**: ```c float convert_raw_temp(int16_t raw) { if (raw & 0x8000) { // 检查符号位(最高位) // 负温度:减1后按位取反[^2] raw = ~(raw - 1); return -(raw * 0.0625f); // 分辨率0.0625°C/LSB } return raw * 0.0625f; // 正温度直接转换 } ``` #### 3. **显示功能错误** - **错误表现**: OLED显示格式错误(如小数位丢失)或串口输出格式不匹配[^3]。 - **修正方案**: ```c // OLED显示(需适配具体驱动库) oled_printf(0, 0, "Temp:%.3fC", temp); // 显示3位小数 // 串口输出调试 printf("Temperature: %.3f C\r\n", temp); // 匹配示例格式[^3] ``` --- ### 二、完整代码参考 ```c #include <stdint.h> // 温度读取函数 int16_t read_ds18b20() { // 1. 初始化DS18B20时序 // 2. 发送温度转换命令(0x44) // 3. 读取暂存器(命令0xBE) uint8_t lsb = read_byte(); // 低字节 uint8_t msb = read_byte(); // 高字节 return (msb << 8) | lsb; // 组合16位数据 } // 温度转换函数 float raw_to_celsius(int16_t raw) { if (raw & 0x8000) { // 负温度检测 raw = ~(raw - 1); // 补码转换[^2] return -(raw * 0.0625f); // 12位分辨率 } return raw * 0.0625f; // 正温度 } // 主流程示例 void main() { int16_t raw = read_ds18b20(); float temp = raw_to_celsius(raw); // OLED显示(示例) oled_show_temp(temp); // 需实现显示驱动 // 串口调试输出 printf("Temperature: %.3f C\r\n", temp); // [^3] } ``` --- ### 三、关键验证点 1. **负温度测试** 将传感器置于低温环境(如0°C以下),检查输出是否正确处理负号及数值。 2. **分辨率验证** 测试25.625°C、25.750°C等典型值,确认小数部分精度[^3]。 3. **数据一致性** 对比原始16进制数据与转换结果,确保补码转换逻辑正确: - 示例:`0xFF5E`(补码) → `-0x00A2` → `-10.125°C` --- ### 错误预防建议 1. 使用`int16_t`类型存储原始温度值,避免符号位处理错误。 2. 在补码转换前优先处理符号位判断。 3. 显示时统一保留3位小数,匹配DS18B20的0.0625°C分辨率[^1][^3]。 通过上述修正,可解决温度数据读取异常、负温度显示错误及输出格式不一致问题。实际部署时需结合具体硬件平台调整时序控制代码。 [^1]: DS18B20温度转换需处理补码格式和0.0625分辨率。 [^2]: 负温度转换需"减1后取反"而非"加1取反"。 [^3]: 串口输出需保留三位小数,OLED需调整字体位置。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值