Arduino 扫描I2C设备的程序

Arduino IO端口有限,使用I2C来进行扩展是一个很好的选择(A4-SDA, A5-SCL)。可以通过下面的程序来完成对I2C,以便确定设备地址。

程序来自 http://www.geek-workshop.com/thread-287-1-1.html ,修正了其中的编译Bug和程序输出结果上的bug,实测工作正常。

Capture

//Below program comes from http://www.geek-workshop.com/thread-287-1-1.html
//According to that page I have fiexed some bugs :
// 1. " rc = twi_writeTo(addr, &data, 0, 1);"
// 2. addr = addr<<1;  This line should be removed
// I have tested below code with my I2C LCD.

#include "Wire.h"
extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

byte start_address = 1;
byte end_address = 127;

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr, 
                void(*callback)(byte address, byte result) ) 
{
  byte rc;
  byte data = 0; // not used, just an address to feed to twi_writeTo()
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr,&data,0,1,1);
    if(rc==0) callback( addr, rc );
  }
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
  Serial.print(addr,DEC);
  //ZT Debug addr = addr<<1;
  Serial.print("\t HEX: 0x");
  Serial.print(addr,HEX);
  Serial.println( (result==0) ? "\t found!":"   ");
//  Serial.print( (addr%4) ? "\t":"\n");
}

// standard Arduino setup()
void setup()
{
    pinMode(13,OUTPUT);
    Wire.begin();

    Serial.begin(9600);
    Serial.println("--- I2C Bus Scanner Test ---");
    Serial.print("starting scanning of I2C bus from ");
    Serial.print(start_address,DEC);
    Serial.print(" to ");
    Serial.print(end_address,DEC);
    Serial.println("...");
    Serial.println();

    // start the scan, will call "scanFunc()" on result from each address
    scanI2CBus( start_address, end_address, scanFunc );

    Serial.print("\n");
    Serial.println("--- I2C Bus Scanner Complete ---");

    digitalWrite(13,HIGH); delay(500); digitalWrite(13,LOW); delay(500);
    digitalWrite(13,HIGH); delay(500); digitalWrite(13,LOW); delay(500);
    digitalWrite(13,HIGH); delay(500); digitalWrite(13,LOW); delay(500);
}

void loop() 
{
}

 

PuttyTel的辅助工具

工作需要通过串口来进行Debug。之前工作环境是Windows XP,一直使用一款软件(我也不清楚具体应该叫做什么名字,因为我下载时它的名字是“好用的串口工具.exe”),如同他的名字一样,确实很好用。但是令人郁闷的是自从切换到了Windows7 64位系统下,这个工具工作不再正常。于是又开始寻找起来新的工具。要求是:不能是盗版,必须支持 Windows 7 64Bit,灵活最好不需要安装,能够将Log记录到文本文件中,使用上必须简单………..

后来用了一段时间的 Putty 发现功能非常强大。美中不足是每次打开操作复杂,首先,运行之后会弹出询问权限的窗口,其次需要手动输入com号,而我使用的是USB串口,经常因为插拔而导致端口的变化,于是每次还要去设备管理器查看当前的端口,在打开设备管理器还会弹出权限窗口……..真的很麻烦。

Putty是开源软件,下载代码后试图修改去掉限制。再后来发现Putty一起发布的有个功能单一的PuttyTel,可以通过命令行方式进行端口的指定和调用,权衡安全性和复杂性最后就编写这个工具软件。所谓安全性,指的是如果我自己编译发布Putty,非常可能在代码中加入后门。如果你是直接使用标准版就不会有此之虞。在这个神奇的xx,上述的担忧绝非杞人忧天,在2012年曾经发生过这样的事情,后面有空的时候我会简单介绍一下。

使用方法非常简单:使用时将这个文件和PuttyTel放在同一个目录下,然后运行之后双击当前端口列表中出现的需要串口即可立即调用起来。

源程序在Source目录下。特别注意这是Delphi XE4 下面Build通过的,并没有使用XE4的新特性,如果你使用其他版本Delphi需要修改对应的头文件。

spc

SerialPortChooser

参考:

1.Putty的官方网站(因为安全问题请不要使用国内的Putty软件,为了方便我在EXE目录下放置了一个官网上下载的PuttyTel,你可以通过比对MD5进行验证)
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

2.关于Putty命令行调用方式来自
http://tartarus.org/~simon/putty-snapshots/htmldoc/Chapter3.html
例如:-serial com4 -sercfg 115200,8,n,1,N

做了一个太阳罐

使用了一块太阳能电池(黑色部分),一块普通充电电池(自己做的电池盒,手艺生疏了),配合QX5252芯片。选用的是焊接好的QX5252电路板,在淘宝上搜索 “太阳能串灯 圣诞灯 灯具用充电升压电路板 太阳能LED驱动器 独家” 可以找到这个卖家。美中不足的是这家卖的太阳能电池都是苏联风格的—-功能不差,外观粗糙。太阳能电池比较小,就这样平放,晒一天估计能让我这个LED工作4小时左右。

俯视:
x1

阳光下充电中:
2

环境暗下来之后LED会自动点亮:
3

QX5252典型应用的电路图(来自 QX5252 SPEC):

sche

多说两句QX5252是专门设计为LED草坪灯的,它的DC升压之后应该是脉冲形式的供电,我买的电路板上多了一个陶片电容应该就是为了让电压输出平稳一些(具体如何我没用使用示波器查看过)。因此,如果你想把这个芯片当作一个DC升压电路来用的话,有可能会出现问题。比如:那种随着时间颜色不断变化的LED玩具,用这个东西供电之后会始终停留在最初的颜色上。QX5252的一个功能是只有环境光线暗下来来的时候才会点亮LED,这应该是通过判断太阳能电池电压来实现的。

如果不使用QX5252芯片,自己构建电路的话我们需要解决如下问题:

1.DC 的升压 (电池电压通常无法点亮LED)
2.电池的防止过充过放 (充电电池的要求,如果你不使用充电电池那么无需考虑)
3.防止电流倒灌(据说加入肖特基二极管就可以了)
4.环境光线的感知 (应该没人想做一只有阳光才会亮,没有阳光绝对不亮的“太阳能电筒”吧)

QX5252 SPEC

QX5252

如果你用Delphi处理文件发现有乱码,不妨考虑一下编码的问题

最近编写了一个间的的程序,主要的代码是

begin
  AssignFile(rFile,'xyz.csv');
  AssignFile(wFile,'111.txt');
  reset(rFile);
  rewrite(wFile);
  s:='';
  i:=0;
  while NOT eof(rFile) do
    begin
      readln(rFile,s);
      writeln(wFile,s);
    end;
  closefile(rFile);
  closefile(wFile);
end.

 

运行之后发现结果竟然并非预期,这个是原始文件内容

org

这是运行之后的结果

fail

多次查找无法确定原因,后来在想到可能是 unicode导致的问题,找到了下面的文章

http://stackoverflow.com/questions/14232900/unicode-text-file-output-differs-between-xe2-and-delphi-2009

但是因为 Delphi2010 并没有 AssignFile(rFile,”,CP_UTF8); 这样的Override,所以直接升级到XE4.再次运行现象消失问题解决。因此,如果你在读取文本文件时遇到奇怪的无法解释的问题,不妨先考虑是否为 unicode 导致。解决方法上,最简单就是升级Delphi版本,此外还可以使用MemoryStream来自行处理。

区分本地磁盘与移动硬盘

这一系列文章是根据cutebunny 的BLOG “windows的磁盘操作” 写成的,主要是部分修改原作中的代码,使之兼容Unicode和Windows 7 64bit. 原文可以在下面的网址找到

http://cutebunny.blog.51cto.com 。 本文是参考 “windows的磁盘操作之九——区分本地磁盘与移动硬盘”写成。

程序实现了区分当前存储设备是硬盘还是移动硬盘的功能。

// gettype.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"

/******************************************************************************
* Function: get the bus type of an disk
* input: drive name (c:)
* output: bus type
* return: Succeed, 0
*         Fail, -1
******************************************************************************/
DWORD GetDriveTypeByBus(const TCHAR *drive, WORD *type)
{
    HANDLE hDevice;               // handle to the drive to be examined
    BOOL result;                 // results flag
    DWORD readed;                   // discard results
 
    STORAGE_DESCRIPTOR_HEADER *pDevDescHeader;
    STORAGE_DEVICE_DESCRIPTOR *pDevDesc;
    DWORD devDescLength;
    STORAGE_PROPERTY_QUERY query;
 
    hDevice = CreateFile(
                    drive, // drive to open
                    GENERIC_READ | GENERIC_WRITE,     // access to the drive
                    FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode
                    NULL,             // default security attributes
                    OPEN_EXISTING,    // disposition
                    0,                // file attributes
                    NULL            // do not copy file attribute
                    );
    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
    {
        fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
        return DWORD(-1);
    }
 
    query.PropertyId = StorageDeviceProperty;
    query.QueryType = PropertyStandardQuery;
 
    pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER));
    if (NULL == pDevDescHeader)
    {
        return (DWORD)-1;
    }
   
    result = DeviceIoControl(
                    hDevice,     // device to be queried
                    IOCTL_STORAGE_QUERY_PROPERTY,     // operation to perform
                    &query,
                    sizeof query,               // no input buffer
                    pDevDescHeader,
                    sizeof(STORAGE_DESCRIPTOR_HEADER),     // output buffer
                    &readed,                 // # bytes returned
                    NULL);      // synchronous I/O
    if (!result)        //fail
    {
        fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError());
        free(pDevDescHeader);
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
 
    devDescLength = pDevDescHeader->Size;
    pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(devDescLength);
    if (NULL == pDevDesc)
    {
        free(pDevDescHeader);
        return (DWORD)-1;
    }
 
    result = DeviceIoControl(
                    hDevice,     // device to be queried
                    IOCTL_STORAGE_QUERY_PROPERTY,     // operation to perform
                    &query,
                    sizeof query,               // no input buffer
                    pDevDesc,
                    devDescLength,     // output buffer
                    &readed,                 // # bytes returned
                    NULL);      // synchronous I/O
    if (!result)        //fail
    {
        fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError());
        free(pDevDescHeader);
        free(pDevDesc);
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
 
    //printf("%d\n", pDevDesc->BusType);
    *type = (WORD)pDevDesc->BusType;
    free(pDevDescHeader);
    free(pDevDesc);
 
    (void)CloseHandle(hDevice);
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	WORD	t;
    TCHAR   *Driver;

	Driver=L"\\\\.\\c:";

	GetDriveTypeByBus(Driver,&t);

	fprintf(stdout, "%x\n",t);

	Driver=L"\\\\.\\d:";

	GetDriveTypeByBus(Driver,&t);

	fprintf(stdout, "%x\n",t);

	getchar();
	return 0;
}

 

运行结果如下 (注意,运行时需要管理员的权限)

hdorrhd

表示一个是 BusTypeAta 另一个是 BusTypeUsb,前者是固定在机器中的硬盘,后者是U盘。

源代码以及可执行程序

gettype

参考:
1.cutebunny 的BLOG “windows的磁盘操作” 可以在这里下载 WindowsDisk

根据分区确定硬盘

这一系列文章是根据cutebunny 的BLOG “windows的磁盘操作” 写成的,主要是部分修改原作中的代码,使之兼容Unicode和Windows 7 64bit. 原文可以在下面的网址找到

http://cutebunny.blog.51cto.com 。 本文是参考 “windows的磁盘操作之四——根据逻辑分区号获得物理磁盘号”写成。实现的功能简单的说就是输入 c: ,程序返回这个

盘符是处于 \\physicalDriveX 上的。

// GetPD.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"

/******************************************************************************
* Function: get disk's physical number from its drive letter
*           e.g. C-->0 (C: is on disk0)
* input: letter, drive letter
* output: N/A
* return: Succeed, disk number
*         Fail, -1
******************************************************************************/
DWORD GetPhysicalDriveFromPartitionLetter(TCHAR letter)
{
    HANDLE hDevice;               // handle to the drive to be examined
    BOOL result;                 // results flag
    DWORD readed;                   // discard results
    STORAGE_DEVICE_NUMBER number;   //use this to get disk numbers
 
    TCHAR path[MAX_PATH];
    wsprintf(path, L"\\\\.\\%c:", letter);
    hDevice = CreateFile(path, // drive to open
                         GENERIC_READ | GENERIC_WRITE,    // access to the drive
                         FILE_SHARE_READ | FILE_SHARE_WRITE,    //share mode
                         NULL,             // default security attributes
                         OPEN_EXISTING,    // disposition
                         0,                // file attributes
                         NULL);            // do not copy file attribute
    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
    {
        fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
        return DWORD(-1);
    }
 
    result = DeviceIoControl(
                hDevice,                // handle to device
                IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode
                NULL,                            // lpInBuffer
                0,                               // nInBufferSize
                &number,           // output buffer
                sizeof(number),         // size of output buffer
                &readed,       // number of bytes returned
                NULL      // OVERLAPPED structure
            );
    if (!result) // fail
    {
        fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());
        (void)CloseHandle(hDevice);
        return (DWORD)-1;
    }
    printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);
 
    (void)CloseHandle(hDevice);
    return number.DeviceNumber;
}


int _tmain(int argc, _TCHAR* argv[])
{
	GetPhysicalDriveFromPartitionLetter('c');	
	getchar();
	return 0;
}

 

运行结果如下 (注意,运行时需要管理员的权限)

lt2phy

其中的 7 是 FILE_DEVICE_DISK, 0 表示 PhysicalDrive0 ,2 表示这个硬盘上有2个分区。

GetPD

参考:

1.cutebunny 的BLOG “windows的磁盘操作” 可以在这里下载 WindowsDisk
2.http://msdn.microsoft.com/en-us/library/windows/desktop/bb968800(v=vs.85).aspx IOCTL_STORAGE_GET_DEVICE_NUMBER control code
3.http://msdn.microsoft.com/en-us/library/windows/desktop/bb968801(v=vs.85).aspx STORAGE_DEVICE_NUMBER structure

哲理小故事:Attitude很重要吗?

有一个经典的小故事,用一种方法来证明“attitude很重要”:

如果令 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 分别等于百分之 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
那么Hard work (努力工作)

H+A+R+D+W+O+R+K 8+1+18+4+23+15+18+11 = 98%

Knowledge(知识)

K+N+O+W+L+E+D+G+E 11+14+15+23+12+5+4+7+5 = 96%

Love(爱情)

L+O+V+E12+15+22+5 = 54%

Luck(好运)

L+U+C+K12+21+3+11 = 47%

(这些我们通常认为重要的东西往往并不是最重要的)

什么能使得生活变得圆满?

是Money(金钱)吗? …

不! M+O+N+E+Y = 13+15+14+5+25 = 72%

是Leaadership(领导能力)吗? …

不! L+E+A+D+E+R+S+H+I+P = 12+5+1+4+5+18+19+9+16 = 89%

那么,什么能使生活变成100%的圆满呢?

每个问题都有其解决之道,只要你把目光放得远一点!

ATTITUDE(心态)

A+T+T+I+T+U+D+E 1+20+20+9+20+21+4+5 = 100%

我们对待工作、生活的态度能够使我们的生活达到100%的圆满。”

我的问题是:除了态度,是否有其他“能够使我们的生活达到100%的圆满”的?

经过查找,至少还有下面的单词:

accumulate|v.积聚,堆积
acknowledge|vt.承认,答谢,报偿
adulthood|n.成人期
affectation|n.假装,虚饰,做作
alienation|n.疏远,转让
analysis|n.分析,分解
anterior|adj.前面的,在前的
apoplectic|n.患中风者adj.中风的,易患中风的
appertain|v.属于
apropos|adj.adv.适当地,恰好的
attitude|n.姿势,态度,看法,意见
avocation|n.(个人)副业,业余爱好
awfully|adv.非常,很,十分
benediction|n.祝福
blissful|adj.有福的
botanist|n.植物学家
bouillon|n.肉汤,牛肉汤
boundary|n.边界,分界线
boycott|n.vt.联合抵制,联合排斥某国货物或与某国绝交
bronchus|n.[医]支气管
cacophony|n.刺耳的音调,不协和音,杂音
candidature|n.候选人的地位,候选人资格
carpenter|n.木匠
chimpanzee|n.[动]非洲的小人猿,黑猩猩
clockwise|adj.顺时针方向的adv.顺时针方向地
companion|n.同伴,共事者
comport|v.相称
congenital|n.adj.天生的,先天的,天赋的
congress|n.(代表)大会,[C~](美国等国的)国会,议会
connivance|n.假装不见,纵容,默许
contented|adj.满足的,心安的
corridor|n.走廊
crudity|n.生,生硬,不熟
culture|n.文化,文明
debarkation|n.下车,下船,登陆
declarative|adj.宣言的,公布的
declension|n.[文法]词尾变化,格变化,倾斜,衰退
decorous|adj.有礼貌的
deliquesce|vi.溶解,解除,液化
delivery|n.递送,交付,分娩,交货,引渡n.[律]财产等的正式移交发送,传输
demobilize|v.复员
denominate|vt.命名adj.有说明性名称的
depletion|n.损耗
dinginess|n.暗淡,肮脏
discernible|adj.可辨别的
discipline|n.纪律,学科v.训练
discommode|vt.使不方便,使为难,使不自由
discredited|adj.不足信的,不名誉的
distrait|adj.心不在焉的
dogmatize|v.武断地提出
drizzle|n.细雨v.下毛毛雨
dumbfound|v.使人哑然失声,使发楞
ebullient|adj.冒泡的,沸腾的,热情的,热情洋溢的
elsewhere|adv.在别处
emasculate|vt.阉割,使柔弱,删削,使无力adj.阉割了的,柔弱的
embodiment|n.体现,具体化,化身
emendation|n.修订,校正,修正
empathetic|adj.(empathic)移情作用的,感情移入的
espouse|vt.嫁娶,支持,赞成
eulogize|vt.称赞,颂扬
eventual|adj.<古>可能的,最后的,结局的,万一的,终于的
excellent|adj.卓越的,极好的
excoriate|v.批判
fatalistic|adj.宿命论的
fatherhood|n.父亲的身份,父性,父权
fluorine|[化]氟(9号元素,符号F)
fountain|n.泉水,喷泉,源泉
groggily|adv.酒醉地,东倒西歪地
grumpy|adj.脾气坏的,性情乖戾的,脾气暴躁的
gullibly|
healthily|adv.健康地
hirsute|adj.多毛的,有粗毛的
hobbyist|n.沉溺于某种癖好者,嗜某爱好成癖的人
holograph|n.亲笔文件,[律]亲笔信,[物]全息图
honeycomb|n.蜂房,蜂巢,蜂脾
hospital|n.医院
imbroglio|n.杂乱的一团,纠葛,纷扰,误解
immature|adj.不成熟的,未完全发展的
inadequacy|n.不充分
inapplicable|adj.不适用的
inefficient|adj.效率低的,效率差的,(指人)不能胜任的,无能的
inflation|n.胀大,夸张,通货膨胀,(物价)暴涨
innovate|vi.改革,创新
inoculate|vt.接种,嫁接
insecticide|n.杀虫剂
intellect|n.智力
interfere|vi.干涉,干预,妨碍,打扰
irritate|vt.激怒,使急躁v.刺激
judiciary|adj.司法的,法院的n.司法部,司法官,审判员
leaderless|adj.无领袖的
liberalism|n.自由主义
liberator|n.解放者,释放者
lightning|n.闪电(“闪电”)英国第一种超音速喷气式战斗机,英60年代的主力机种。
likelihood|n.可能,可能性
limpidly|adv.清澈地,透明地
litotes|n.间接肯定法,反语法
lubricant|n.滑润剂
macrocosm|n.宏观世界
magnetize|vt.使磁化,吸引vi.受磁
martinet|n.规律严肃的人,严格的人
masochism|n.[心]性受虐狂,受虐色情狂,受虐狂
maximize|vt.取…最大值,最佳化
mercantile|adj.商人的,商业的,经商的,重商主义的,以金钱为目的的
mercurial|adj.墨丘利神的,水星的,雄辩机智的,活泼善变的,水银的n.水银剂,汞剂
merrily|adv.愉快地,高兴地
misdirect|vt.误导,写错地址
molecular|adj.[化]分子的,由分子组成的
nastily|adv.污秽地,不洁地
nestling|n.未离巢的雏鸟,婴儿
nihilist|n.虚无主义者
nostalgic|adj.乡愁的,怀旧的
operetta|n.小歌剧
ornament|n.装饰物,教堂用品vt.装饰,修饰
outset|n.开端,开始
palpitate|v.跳动
pasture|n.牧地,草原,牧场v.放牧,牧(牛、羊)等,吃草
personage|n.要人,名流,个人
personal|adj.私人的,个人的,亲自的,容貌的,身体的,人身的,针对个人的adj.[语法]人称的
perturb|v.感到不安
plastered|adj.醉醺醺的
plebiscite|n.平民制定法,公民投票
plummet|n.铅锤,重荷vi.垂直落下
plumule|n.幼芽,棉毛
postdate|vt.填迟…的日期n.事后日期
preordain|vt.预定,预先注定命运
prevent|v.防止,预防
primary|adj.第一位的,主要的,初步的,初级的,原来的,根源的
printer|n.印刷工,打印机
producer|n.生产者,制作者,演出人,(电影)制片人
profuse|adj.极其丰富的
progeny|n.后裔
promisee|n.[律]受约人,承诺人
pumpkin|n.南瓜
pursue|vt.追赶,追踪,追击,继续,从事
quadrangle|n.四角形,四边形,方院,方庭(尤指牛津大学等学院中者)
quarry|n.采石场,(知识、消息等的)来源vt.挖出,苦心找出vi.费力地找
quarter|n.四分之一,方向,地区,方面,季,季度,一刻钟num.四分之一,刻
radiocarbon|n.放射性碳,碳的放射性同位元素
raillery|n.开玩笑,逗趣
receptor|n.接受器,感受器,受体
reciprocal|adj.互惠的,相应的,倒数的,彼此相反的n.倒数,互相起作用的事物
refinery|n.精炼厂
renovate|vt.革新,刷新,修复
repress|vt.<美>再压,补充加压vi.压制
reprint|v.再版
reprobate|v.非难
reputable|adj.著名的
reshuffle|n.改组v.改组
restore|vt.恢复,使回复,归还,交还,修复,重建
retiring|adj.退休的
reversal|n.颠倒,反转,反向,逆转,撤销
saintly|adj.圣洁的
salacious|adj.猥亵的,好色的
savory|adj.风味极佳的,可口的,味美的n.使人开胃的菜肴
scuttle|n.天窗,舱室小孔,煤桶,急速逃走vi.急促地跑,急忙撤退vt.凿沉,毁坏,毁坏
selective|adj.选择的,选择性的
session|n.会议,开庭
shattered|粉碎
shibboleth|n.口令
simulate|vt.模拟,模仿,假装,冒充
smitten|v.smite的过去分词
snobbery|n.势利
socialism|n.社会主义,社会主义运动
spirited|adj.英勇的
splashy|adj.易溅的,泼溅的,有色斑的
squint|v.斜视
status|n.身份,地位,情形,状况
stress|n.重压,逼迫,压力,重点,着重,强调,重音vt.着重,强调,重读
subsume|v.包容,包含
surcharge|n.超载,追加罚款,额外费vt.使装载过多,追加罚款
surely|adv.的确地,安全地
swollen|adj.肿胀的
syndicate|n.企业联合,[经]辛迪加,财团v.联合成辛迪加
synergic|adj.协作的,合作的
telephone|n.电话,电话机v.打电话
telescope|n.望远镜v.压缩
temperance|n.节欲,戒酒,禁酒,(气候等的)温和
temporal|adj.时间的,当时的,暂时的,现世的,世俗的,[解]颞的n.世间万物,教会财产
therefore|adv.因此,所以
thickening|n.使变厚,增厚过程
thirty|num.三十
thorny|adj.多刺的,痛苦的
towards|prep.向,朝,对面,接近,对,有助于
traction|n.牵引
truism|n.真实性
turkey|n.火鸡,无用的东西
undergird|v.加强,巩固…的底部
underlay|vt.铺在…下面,垫起vi.向下延伸n.衬垫物
unfasten|vt.解开,放松
unkempt|adj.蓬乱的,粗野的,不整洁的
useless|adj.无用的,无效的,无益的,无价值的
utensil|n.器具
variety|n.变化,多样性,种种,品种,种类
verbalize|v.描述
vouchsafe|vt.赐予,允许
whenever|conj.无论何时,随时n.只要
whiskey|n.威士忌酒adj.威士忌酒的
wholesale|n.批发,趸售adj.批发的,[喻]大规模的
writing|n.笔迹,作品,著述

我只想说明,态度真的很重要,许许多多年前我就发现了这一点,以至于我的师父曾经夸奖过我“有错误马上就承认,但是改不改就是另外的事情”。

但是用上面字母累加的方式来证明这一点是非常愚蠢的做法,弱智到20年前国产《知音》杂志的水平。

wordscore

可执行文件+源程序+字典文件

ScoreWords

使用Indy10实现的简单的 Console下发送邮件

使用Indy10实现的简单的 Console下发送邮件

这个例子使用了 Indy10 通过 SMTP来发送邮件。通过命令行参数来指定文件的内容(Body),并且能够添加附件。

使用方法例如:

scmail /server[smtp.sina.com] /to[405623608@qq.com] /from[zoologist@sina.com] /subject[Hi, buddy] /body[c:\body.txt] /atta[c:\1.bin] /user[zoologist@sina.com] /password[xxxx]

当然,上面的to可以换成你自己的邮箱,from和user 需要填写为你自己的邮箱地址,还有最后的密码也要填写上你自己邮箱的密码(目前免费邮箱发送邮件都要进行身份验证,当然你也可以临时注册一个邮箱)。

运行结果:

scmail

代码和可执行程序

scmail

Ubuntu 遇到能看到但是无法执行的可执行程序的解决办法

64位 Ubuntu 下,可能出现出现一个能看到但是无法执行的可执行文件。尝试执行时,会出现 “bash: ./name: No such file or directory”的错误提示。

产生这个问题的一个原因可能是:你的可执行程序是 32位的,而系统是64位的,所以无法正常执行(当然在这步之前还请确定权限正确)。

最后解决方法是:用下面命令安装一个兼容库

sudo apt-get install ia32-libs

之后再尝试执行之前的程序

取得硬盘分区信息

这一系列文章是根据cutebunny 的BLOG “windows的磁盘操作” 写成的,主要是部分修改原作中的代码,使之兼容Unicode和Windows 7 64bit. 原文可以在下面的网址找到

http://cutebunny.blog.51cto.com 。 本文是参考 “windows的磁盘操作之三——获取和删除磁盘分区信息”写成。

程序实现了获得当前硬盘分区信息的功能。

// getpart.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"

int _tmain(int argc, _TCHAR* argv[])
{
	 HANDLE hDevice;               // handle to the drive to be examined
     BOOL result;                  // results flag
     DWORD readed;                 // discard results
	 DWORD szNewLayout;
	 DRIVE_LAYOUT_INFORMATION_EX *dl = NULL;
	 DWORD	i;

	// 特别注意 DRIVE_LAYOUT_INFORMATION_EX 结构体的大小,即使只有一个分区,也需要预留出4个分区的大小
    // 下面是预留了10个分区的大小。如果直接使用该结构体而不扩大大小会导致 GetLastError =0x7A
     szNewLayout=sizeof(DRIVE_LAYOUT_INFORMATION_EX) + 10 * sizeof(PARTITION_INFORMATION_EX);
	 dl = (DRIVE_LAYOUT_INFORMATION_EX*) new BYTE[szNewLayout];

     hDevice = CreateFile(
                L"\\\\.\\PhysicalDrive0", // drive to open
                GENERIC_READ | GENERIC_WRITE,     // access to the drive
                FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode
                NULL,             // default security attributes
                OPEN_EXISTING,    // disposition
                0,                // file attributes
                NULL            // do not copy file attribute
                );
     if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
     {
         fprintf(stderr, "CreateFile() Error: 0x%X\n", GetLastError());
     }

     result = DeviceIoControl(
                hDevice,               // handle to device
                IOCTL_DISK_GET_DRIVE_LAYOUT_EX, // dwIoControlCode
                NULL,                           // lpInBuffer
                0,                              // nInBufferSize
                dl,           // output buffer
                szNewLayout,         // size of output buffer
                &readed,      // number of bytes returned
                NULL     // OVERLAPPED structure
                );
    if (!result)
    {
        fprintf(stderr, "IOCTL_DISK_GET_DRIVE_LAYOUT_EX Error: 0x%X\n", GetLastError());
        (void)CloseHandle(hDevice);
    }
   
	if (dl->PartitionStyle == PARTITION_STYLE_MBR)
	{
		fprintf(stdout, "It's MBR\n", GetLastError());
	}
	if (dl->PartitionStyle == PARTITION_STYLE_GPT)
	{
		fprintf(stdout, "It's GPT\n", GetLastError());
	}
	if (dl->PartitionStyle == PARTITION_STYLE_RAW)
	{
		fprintf(stdout, "It's RAW\n", GetLastError());
	}
	//PartitionCount 这个参数不准确,它给出的是4的整数倍。要想准确,需要结构体中其他的来确定
	//
    //The number of partitions on the drive. On hard disks with the MBR layout, 
	//this value will always be a multiple of 4. Any partitions that are actually 
	//unused will have a partition type of PARTITION_ENTRY_UNUSED (0) set in the PartitionType 
	//member of the PARTITION_INFORMATION_MBR structure of the Mbr member of the
	//PARTITION_INFORMATION_EX structure of the PartitionEntry member of this structure.
	fprintf(stdout, "There are %d partitions in PhysicalDrive0\n", dl->PartitionCount);

	for (i=0;i<dl->PartitionCount; i++)
	{
		fprintf(stdout, "Partition[%d] Start Ofs[%llX] Length[%lldMB]\n",
				dl->PartitionEntry[i].PartitionNumber, 
				dl->PartitionEntry[i].StartingOffset,
				dl->PartitionEntry[i].PartitionLength.QuadPart / 1024 /1024);
	}
	delete(dl);

	getchar();
	return 0;
}

 

运行结果如下 (注意,运行时需要管理员的权限)
getpart

getpart

参考:
1.cutebunny 的BLOG “windows的磁盘操作” 可以在这里下载 WindowsDisk